ソースを参照

Merge branch 'next' of https://gitee.com/neolu/Admin.NET into next

keepnode 2 年 前
コミット
10f960a3c2
97 ファイル変更3439 行追加1001 行削除
  1. 1 1
      Admin.NET/Admin.NET.Application/Configuration/CodeGen.json
  2. 1 1
      Admin.NET/Admin.NET.Application/Configuration/Upload.json
  3. 11 11
      Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj
  4. 28 0
      Admin.NET/Admin.NET.Core/Attribute/NotEmptyAttribute.cs
  5. 37 37
      Admin.NET/Admin.NET.Core/Cache/CacheSetup.cs
  6. 1 1
      Admin.NET/Admin.NET.Core/Entity/SysConfig.cs
  7. 0 2
      Admin.NET/Admin.NET.Core/Entity/SysOpenAccess.cs
  8. 190 164
      Admin.NET/Admin.NET.Core/Entity/SysWechatPay.cs
  9. 97 0
      Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs
  10. 15 3
      Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs
  11. 31 0
      Admin.NET/Admin.NET.Core/EventBus/EventHandlerMonitor.cs
  12. 1 1
      Admin.NET/Admin.NET.Core/EventBus/RedisQueue.cs
  13. 43 21
      Admin.NET/Admin.NET.Core/EventBus/RetryEventHandlerExecutor.cs
  14. 0 41
      Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs
  15. 1 1
      Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs
  16. 205 197
      Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs
  17. 2 2
      Admin.NET/Admin.NET.Core/Service/Auth/SysAuthService.cs
  18. 23 23
      Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs
  19. 2 2
      Admin.NET/Admin.NET.Core/Service/DataBase/SysDatabaseService.cs
  20. 1 1
      Admin.NET/Admin.NET.Core/Service/Dict/SysDictTypeService.cs
  21. 38 44
      Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs
  22. 106 106
      Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs
  23. 0 1
      Admin.NET/Admin.NET.Core/Service/Message/SysSmsService.cs
  24. 4 0
      Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs
  25. 47 1
      Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs
  26. 25 1
      Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayOutput.cs
  27. 315 46
      Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs
  28. 2 1
      Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatService.cs
  29. 4 10
      Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs
  30. 20 21
      Admin.NET/Admin.NET.Core/Util/CommonUtil.cs
  31. 10 3
      Admin.NET/Admin.NET.Core/Util/ComputerUtil.cs
  32. 2 0
      Admin.NET/Admin.NET.Core/Util/VerifyFileExtensionName.cs
  33. 16 4
      Admin.NET/Admin.NET.Web.Core/Startup.cs
  34. 22 13
      Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm
  35. 2 2
      Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm
  36. 1 1
      Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Middleware/ApprovalFlowMiddleware.cs
  37. 2 1
      Admin.NET/Plugins/Admin.NET.Plugin.GoView/Entity/GoViewPro.cs
  38. 1 0
      Admin.NET/Plugins/Admin.NET.Plugin.GoView/Entity/GoViewProData.cs
  39. 1 1
      Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj
  40. 9 9
      Web/package.json
  41. 0 75
      Web/src/api-services/apis/sys-auth-api.ts
  42. 100 8
      Web/src/api-services/apis/sys-config-api.ts
  43. 96 0
      Web/src/api-services/apis/sys-sms-api.ts
  44. 529 22
      Web/src/api-services/apis/sys-wechat-pay-api.ts
  45. 8 8
      Web/src/api-services/models/add-org-input.ts
  46. 71 0
      Web/src/api-services/models/admin-result-list-sys-wechat-refund.ts
  47. 69 0
      Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-wechat-pay.ts
  48. 69 0
      Web/src/api-services/models/admin-result-sys-wechat-refund.ts
  49. 69 0
      Web/src/api-services/models/admin-result-wechat-pay-para-output.ts
  50. 69 0
      Web/src/api-services/models/admin-result-wechat-pay-transaction-output.ts
  51. 38 0
      Web/src/api-services/models/batch-config-input.ts
  52. 8 0
      Web/src/api-services/models/enum-entity.ts
  53. 12 0
      Web/src/api-services/models/index.ts
  54. 8 0
      Web/src/api-services/models/login-user-output.ts
  55. 79 0
      Web/src/api-services/models/sql-sugar-paged-list-sys-wechat-pay.ts
  56. 24 0
      Web/src/api-services/models/sys-wechat-pay.ts
  57. 182 0
      Web/src/api-services/models/sys-wechat-refund.ts
  58. 8 8
      Web/src/api-services/models/update-org-input.ts
  59. 76 0
      Web/src/api-services/models/wechat-pay-page-input.ts
  60. 58 0
      Web/src/api-services/models/wechat-pay-para-output.ts
  61. 54 0
      Web/src/api-services/models/wechat-pay-refund-domestic-input.ts
  62. 16 0
      Web/src/api-services/models/wechat-pay-transaction-input.ts
  63. 41 0
      Web/src/api-services/models/wechat-pay-transaction-output.ts
  64. 31 0
      Web/src/api/system/weChatPay.ts
  65. 1 1
      Web/src/components/table/index.vue
  66. 11 2
      Web/src/layout/navBars/topBar/userNews.vue
  67. 8 8
      Web/src/stores/themeConfig.ts
  68. 2 1
      Web/src/stores/userInfo.ts
  69. 28 0
      Web/src/utils/authFunction.ts
  70. 2 1
      Web/src/utils/base64Conver.ts
  71. 1 2
      Web/src/utils/formatTime.ts
  72. 17 0
      Web/src/utils/json-utils.ts
  73. 2 0
      Web/src/utils/storage.ts
  74. 12 3
      Web/src/views/home/notice/index.vue
  75. 35 65
      Web/src/views/mqttx/index.vue
  76. 1 1
      Web/src/views/system/codeGen/index.vue
  77. 5 1
      Web/src/views/system/database/index.vue
  78. 1 1
      Web/src/views/system/dict/component/editDictData.vue
  79. 2 2
      Web/src/views/system/dict/index.vue
  80. 1 1
      Web/src/views/system/file/index.vue
  81. 2 2
      Web/src/views/system/job/index.vue
  82. 1 1
      Web/src/views/system/ldap/index.vue
  83. 1 1
      Web/src/views/system/log/difflog/index.vue
  84. 1 1
      Web/src/views/system/log/exlog/index.vue
  85. 1 1
      Web/src/views/system/log/oplog/index.vue
  86. 1 1
      Web/src/views/system/log/vislog/index.vue
  87. 1 1
      Web/src/views/system/notice/index.vue
  88. 1 1
      Web/src/views/system/onlineUser/index.vue
  89. 1 1
      Web/src/views/system/openAccess/index.vue
  90. 1 1
      Web/src/views/system/plugin/index.vue
  91. 1 1
      Web/src/views/system/print/index.vue
  92. 1 1
      Web/src/views/system/region/index.vue
  93. 1 1
      Web/src/views/system/role/index.vue
  94. 1 1
      Web/src/views/system/tenant/index.vue
  95. 1 1
      Web/src/views/system/user/index.vue
  96. 261 0
      Web/src/views/system/weChatPay/index.vue
  97. 1 1
      Web/src/views/system/weChatUser/index.vue

+ 1 - 1
Admin.NET/Admin.NET.Application/Configuration/CodeGen.json

@@ -3,7 +3,7 @@
 
   // 代码生成配置项-程序集名称集合
   "CodeGen": {
-    "EntityAssemblyNames": [ "Admin." ],
+    "EntityAssemblyNames": [ "Admin.NET.Core", "Admin.NET.Application" ],
     "BaseEntityNames": [ "EntityTenantId", "EntityTenant", "EntityTenantBaseData", "EntityBaseData", "EntityBase", "EntityBaseId" ],
     "EntityBaseColumn": {
       "EntityTenantId": [ "Id", "TenantId" ],

+ 1 - 1
Admin.NET/Admin.NET.Application/Configuration/Upload.json

@@ -4,7 +4,7 @@
   "Upload": {
     "Path": "Upload/{yyyy}/{MM}/{dd}", // 文件上传目录
     "MaxSize": 51200, // 文件最大限制KB:1024*50
-    "ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "video/mp4", "application/wps-office.docx", "application/wps-office.xlsx", "application/wps-office.pptx" ],
+    "ContentType": [ "image/jpg", "image/png", "image/jpeg", "image/gif", "image/bmp", "text/plain", "application/pdf", "application/msword", "application/vnd.ms-excel", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "video/mp4", "application/wps-office.docx", "application/wps-office.xlsx", "application/wps-office.pptx", "application/vnd.android.package-archive" ],
     "EnableMd5": false // 启用文件MDF5验证-防止重复上传
   },
   "OSSProvider": {

+ 11 - 11
Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj

@@ -17,27 +17,27 @@
     <PackageReference Include="AngleSharp" Version="1.1.2" />
     <PackageReference Include="AspectCore.Extensions.Reflection" Version="2.4.0" />
     <PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
-    <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.14.3" />
-    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4.2" />
-    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.4.2" />
-    <PackageReference Include="Furion.Pure" Version="4.9.4.2" />
+    <PackageReference Include="Elastic.Clients.Elasticsearch" Version="8.14.4" />
+    <PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4.3" />
+    <PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.4.3" />
+    <PackageReference Include="Furion.Pure" Version="4.9.4.3" />
     <PackageReference Include="IPTools.China" Version="1.6.0" />
     <PackageReference Include="IPTools.International" Version="1.6.0" />
     <PackageReference Include="Magicodes.IE.Excel" Version="2.7.5.1" />
     <PackageReference Include="Magicodes.IE.Pdf" Version="2.7.5.1" />
     <PackageReference Include="Magicodes.IE.Word" Version="2.7.5.1" />
-    <PackageReference Include="MailKit" Version="4.6.0" />
-    <PackageReference Include="NewLife.Redis" Version="5.7.2024.602" />
+    <PackageReference Include="MailKit" Version="4.7.0" />
+    <PackageReference Include="NewLife.Redis" Version="5.7.2024.701" />
     <PackageReference Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
-    <PackageReference Include="QRCoder" Version="1.5.1" />
+    <PackageReference Include="QRCoder" Version="1.6.0" />
     <PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
     <PackageReference Include="SixLabors.ImageSharp.Web" Version="3.1.2" />
     <PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.3.0" />
-    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.5.0" />
+    <PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.6.0" />
     <PackageReference Include="SqlSugarCore" Version="5.1.4.160" />
-    <PackageReference Include="SSH.NET" Version="2024.0.0" />
-    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.2" />
-    <PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1036" />
+    <PackageReference Include="SSH.NET" Version="2024.1.0" />
+    <PackageReference Include="System.Linq.Dynamic.Core" Version="1.4.3" />
+    <PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1041" />
     <PackageReference Include="UAParser" Version="3.1.47" />
     <PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
   </ItemGroup>

+ 28 - 0
Admin.NET/Admin.NET.Core/Attribute/NotEmptyAttribute.cs

@@ -0,0 +1,28 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 校验集合不能为空
+/// </summary>
+[SuppressSniffer]
+public class NotEmptyAttribute : ValidationAttribute
+{
+    /// <summary>
+    /// 校验集合不能为空
+    /// </summary>
+    /// <param name="value"></param>
+    /// <returns></returns>
+    public override bool IsValid(object value) => (value as IEnumerable)?.GetEnumerator().MoveNext() ?? false;
+
+    /// <summary>
+    /// 错误信息
+    /// </summary>
+    /// <param name="name"></param>
+    /// <returns></returns>
+    public override string FormatErrorMessage(string name) => base.FormatErrorMessage(name);
+}

+ 37 - 37
Admin.NET/Admin.NET.Core/Cache/CacheSetup.cs

@@ -1,38 +1,38 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using Microsoft.Extensions.DependencyInjection.Extensions;
-using NewLife.Caching.Services;
-
-namespace Admin.NET.Core;
-
-public static class CacheSetup
-{
-    /// <summary>
-    /// 缓存注册(新生命Redis组件)
-    /// </summary>
-    /// <param name="services"></param>
-    public static void AddCache(this IServiceCollection services)
-    {
-        var cacheOptions = App.GetConfig<CacheOptions>("Cache", true);
-        if (cacheOptions.CacheType == CacheTypeEnum.Redis.ToString())
-        {
-            var redis = new FullRedis(new RedisOptions
-            {
-                Configuration = cacheOptions.Redis.Configuration,
-                Prefix = cacheOptions.Redis.Prefix
-            });
-            if (cacheOptions.Redis.MaxMessageSize > 0)
-                redis.MaxMessageSize = cacheOptions.Redis.MaxMessageSize;
-
-            // 注入 Redis 缓存提供者
-            services.AddSingleton<ICacheProvider>(p => new RedisCacheProvider(p) { Cache = redis });
-        }
-
-        // 内存缓存兜底。在没有配置Redis时,使用内存缓存,逻辑代码无需修改
-        services.TryAddSingleton<ICacheProvider, CacheProvider>();
-    }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using NewLife.Caching.Services;
+
+namespace Admin.NET.Core;
+
+public static class CacheSetup
+{
+    /// <summary>
+    /// 缓存注册(新生命Redis组件)
+    /// </summary>
+    /// <param name="services"></param>
+    public static void AddCache(this IServiceCollection services)
+    {
+        var cacheOptions = App.GetConfig<CacheOptions>("Cache", true);
+        if (cacheOptions.CacheType == CacheTypeEnum.Redis.ToString())
+        {
+            var redis = new FullRedis(new RedisOptions
+            {
+                Configuration = cacheOptions.Redis.Configuration,
+                Prefix = cacheOptions.Redis.Prefix
+            });
+            if (cacheOptions.Redis.MaxMessageSize > 0)
+                redis.MaxMessageSize = cacheOptions.Redis.MaxMessageSize;
+
+            // 注入 Redis 缓存提供者
+            services.AddSingleton<ICacheProvider>(p => new RedisCacheProvider(p) { Cache = redis });
+        }
+
+        // 内存缓存兜底。在没有配置Redis时,使用内存缓存,逻辑代码无需修改
+        services.TryAddSingleton<ICacheProvider, CacheProvider>();
+    }
 }

+ 1 - 1
Admin.NET/Admin.NET.Core/Entity/SysConfig.cs

@@ -12,7 +12,7 @@ namespace Admin.NET.Core;
 [SugarTable(null, "系统参数配置表")]
 [SysTable]
 [SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
-[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc)]
+[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc, IsUnique = true)]
 public partial class SysConfig : EntityBase
 {
     /// <summary>

+ 0 - 2
Admin.NET/Admin.NET.Core/Entity/SysOpenAccess.cs

@@ -51,8 +51,6 @@ public partial class SysOpenAccess : EntityBase
     /// <summary>
     /// 绑定用户
     /// </summary>
-    [Newtonsoft.Json.JsonIgnore]
-    [System.Text.Json.Serialization.JsonIgnore]
     [Navigate(NavigateType.OneToOne, nameof(BindUserId))]
     public SysUser BindUser { get; set; }
 }

+ 190 - 164
Admin.NET/Admin.NET.Core/Entity/SysWechatPay.cs

@@ -1,165 +1,191 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// 系统微信支付表
-/// </summary>
-[SugarTable(null, "系统微信支付表")]
-[SysTable]
-public partial class SysWechatPay : EntityBase
-{
-    /// <summary>
-    /// 微信商户号
-    /// </summary>
-    [SugarColumn(ColumnDescription = "微信商户号")]
-    [Required]
-    public virtual string MerchantId { get; set; }
-
-    /// <summary>
-    /// 服务商AppId
-    /// </summary>
-    [SugarColumn(ColumnDescription = "服务商AppId")]
-    [Required]
-    public virtual string AppId { get; set; }
-
-    /// <summary>
-    /// 商户订单号
-    /// </summary>
-    [SugarColumn(ColumnDescription = "商户订单号")]
-    [Required]
-    public virtual string OutTradeNumber { get; set; }
-
-    /// <summary>
-    /// 支付订单号
-    /// </summary>
-    [SugarColumn(ColumnDescription = "支付订单号")]
-    [Required]
-    public virtual string TransactionId { get; set; }
-
-    /// <summary>
-    /// 交易类型
-    /// </summary>
-    [SugarColumn(ColumnDescription = "交易类型")]
-    public string? TradeType { get; set; }
-
-    /// <summary>
-    /// 交易状态
-    /// </summary>
-    [SugarColumn(ColumnDescription = "交易状态")]
-    public string? TradeState { get; set; }
-
-    /// <summary>
-    /// 交易状态描述
-    /// </summary>
-    [SugarColumn(ColumnDescription = "交易状态描述")]
-    public string? TradeStateDescription { get; set; }
-
-    /// <summary>
-    /// 付款银行类型
-    /// </summary>
-    [SugarColumn(ColumnDescription = "付款银行类型")]
-    public string? BankType { get; set; }
-
-    /// <summary>
-    /// 订单总金额
-    /// </summary>
-    [SugarColumn(ColumnDescription = "订单总金额")]
-    public int Total { get; set; }
-
-    /// <summary>
-    /// 用户支付金额
-    /// </summary>
-    [SugarColumn(ColumnDescription = "用户支付金额")]
-    public int? PayerTotal { get; set; }
-
-    /// <summary>
-    /// 支付完成时间
-    /// </summary>
-    [SugarColumn(ColumnDescription = "支付完成时间")]
-    public DateTimeOffset? SuccessTime { get; set; }
-
-    /// <summary>
-    /// 交易结束时间
-    /// </summary>
-    [SugarColumn(ColumnDescription = "交易结束时间")]
-    public DateTimeOffset? ExpireTime { get; set; }
-
-    /// <summary>
-    /// 商品描述
-    /// </summary>
-    [SugarColumn(ColumnDescription = "商品描述")]
-    public string? Description { get; set; }
-
-    /// <summary>
-    /// 场景信息
-    /// </summary>
-    [SugarColumn(ColumnDescription = "场景信息")]
-    public string? Scene { get; set; }
-
-    /// <summary>
-    /// 附加数据
-    /// </summary>
-    [SugarColumn(ColumnDescription = "附加数据")]
-    public string? Attachment { get; set; }
-
-    /// <summary>
-    /// 优惠标记
-    /// </summary>
-    [SugarColumn(ColumnDescription = "优惠标记")]
-    public string? GoodsTag { get; set; }
-
-    /// <summary>
-    /// 结算信息
-    /// </summary>
-    [SugarColumn(ColumnDescription = "结算信息")]
-    public string? Settlement { get; set; }
-
-    /// <summary>
-    /// 回调通知地址
-    /// </summary>
-    [SugarColumn(ColumnDescription = "回调通知地址")]
-    public string? NotifyUrl { get; set; }
-
-    /// <summary>
-    /// 备注
-    /// </summary>
-    [SugarColumn(ColumnDescription = "备注")]
-    public string? Remark { get; set; }
-
-    /// <summary>
-    /// 微信OpenId标识
-    /// </summary>
-    [SugarColumn(ColumnDescription = "微信OpenId标识")]
-    public string? OpenId { get; set; }
-
-    /// <summary>
-    /// 关联微信用户
-    /// </summary>
-    [Newtonsoft.Json.JsonIgnore]
-    [System.Text.Json.Serialization.JsonIgnore]
-    [Navigate(NavigateType.OneToOne, nameof(OpenId))]
-    public SysWechatUser SysWechatUser { get; set; }
-
-    /// <summary>
-    /// 子商户号
-    /// </summary>
-    [SugarColumn(ColumnDescription = "子商户号")]
-    public string? SubMerchantId { get; set; }
-
-    /// <summary>
-    /// 子商户AppId
-    /// </summary>
-    [SugarColumn(ColumnDescription = "回调通知地址")]
-    public string? SubAppId { get; set; }
-
-    /// <summary>
-    /// 子商户唯一标识
-    /// </summary>
-    [SugarColumn(ColumnDescription = "子商户唯一标识")]
-    public string? SubOpenId { get; set; }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 系统微信支付表
+/// </summary>
+[SugarTable(null, "系统微信支付表")]
+[SysTable]
+[SugarIndex("idx_{table}_BusinessId", nameof(BusinessId), OrderByType.Asc)]
+[SugarIndex("idx_{table}_TradeState", nameof(TradeState), OrderByType.Asc)]
+[SugarIndex("idx_{table}_Tags", nameof(Tags), OrderByType.Asc)]
+public partial class SysWechatPay : EntityBase
+{
+    /// <summary>
+    /// 微信商户号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "微信商户号")]
+    [Required]
+    public virtual string MerchantId { get; set; }
+
+    /// <summary>
+    /// 服务商AppId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "服务商AppId")]
+    [Required]
+    public virtual string AppId { get; set; }
+
+    /// <summary>
+    /// 商户订单号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "商户订单号")]
+    [Required]
+    public virtual string OutTradeNumber { get; set; }
+
+    /// <summary>
+    /// 支付订单号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "支付订单号")]
+    [Required]
+    public virtual string TransactionId { get; set; }
+
+    /// <summary>
+    /// 交易类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "交易类型")]
+    public string? TradeType { get; set; }
+
+    /// <summary>
+    /// 交易状态
+    /// </summary>
+    [SugarColumn(ColumnDescription = "交易状态")]
+    public string? TradeState { get; set; }
+
+    /// <summary>
+    /// 交易状态描述
+    /// </summary>
+    [SugarColumn(ColumnDescription = "交易状态描述")]
+    public string? TradeStateDescription { get; set; }
+
+    /// <summary>
+    /// 付款银行类型
+    /// </summary>
+    [SugarColumn(ColumnDescription = "付款银行类型")]
+    public string? BankType { get; set; }
+
+    /// <summary>
+    /// 订单总金额
+    /// </summary>
+    [SugarColumn(ColumnDescription = "订单总金额")]
+    public int Total { get; set; }
+
+    /// <summary>
+    /// 用户支付金额
+    /// </summary>
+    [SugarColumn(ColumnDescription = "用户支付金额")]
+    public int? PayerTotal { get; set; }
+
+    /// <summary>
+    /// 支付完成时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "支付完成时间")]
+    public DateTime? SuccessTime { get; set; }
+
+    /// <summary>
+    /// 交易结束时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "交易结束时间")]
+    public DateTime? ExpireTime { get; set; }
+
+    /// <summary>
+    /// 商品描述
+    /// </summary>
+    [SugarColumn(ColumnDescription = "商品描述")]
+    public string? Description { get; set; }
+
+    /// <summary>
+    /// 场景信息
+    /// </summary>
+    [SugarColumn(ColumnDescription = "场景信息")]
+    public string? Scene { get; set; }
+
+    /// <summary>
+    /// 附加数据
+    /// </summary>
+    [SugarColumn(ColumnDescription = "附加数据")]
+    public string? Attachment { get; set; }
+
+    /// <summary>
+    /// 优惠标记
+    /// </summary>
+    [SugarColumn(ColumnDescription = "优惠标记")]
+    public string? GoodsTag { get; set; }
+
+    /// <summary>
+    /// 结算信息
+    /// </summary>
+    [SugarColumn(ColumnDescription = "结算信息")]
+    public string? Settlement { get; set; }
+
+    /// <summary>
+    /// 回调通知地址
+    /// </summary>
+    [SugarColumn(ColumnDescription = "回调通知地址")]
+    public string? NotifyUrl { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    [SugarColumn(ColumnDescription = "备注")]
+    public string? Remark { get; set; }
+
+    /// <summary>
+    /// 微信OpenId标识
+    /// </summary>
+    [SugarColumn(ColumnDescription = "微信OpenId标识")]
+    public string? OpenId { get; set; }
+
+    /// <summary>
+    /// 业务标签,用来区分做什么业务
+    /// </summary>
+    /// <remarks>
+    /// Tags标识用来区分这个支付记录对应什么业务从而确定相关联的表名,
+    /// 再结合BusinessId保存了对应的业务数据的ID,就可以确定这个支付
+    /// 记录与哪一条业务数据相关联
+    /// </remarks>
+    [SugarColumn(ColumnDescription = "业务标签,用来区分做什么业务", Length = 64)]
+    public string? Tags { get; set; }
+
+    /// <summary>
+    /// 对应业务的主键
+    /// </summary>
+    [SugarColumn(ColumnDescription = "对应业务的主键")]
+    public long BusinessId { get; set; }
+
+    /// <summary>
+    /// 付款二维码内容
+    /// </summary>
+    [SugarColumn(ColumnDescription = "付款二维码内容")]
+    public string? QrcodeContent { get; set; }
+
+    /// <summary>
+    /// 关联微信用户
+    /// </summary>
+    [Newtonsoft.Json.JsonIgnore]
+    [System.Text.Json.Serialization.JsonIgnore]
+    [Navigate(NavigateType.OneToOne, nameof(OpenId))]
+    public SysWechatUser SysWechatUser { get; set; }
+
+    /// <summary>
+    /// 子商户号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "子商户号")]
+    public string? SubMerchantId { get; set; }
+
+    /// <summary>
+    /// 子商户AppId
+    /// </summary>
+    [SugarColumn(ColumnDescription = "回调通知地址")]
+    public string? SubAppId { get; set; }
+
+    /// <summary>
+    /// 子商户唯一标识
+    /// </summary>
+    [SugarColumn(ColumnDescription = "子商户唯一标识")]
+    public string? SubOpenId { get; set; }
 }

+ 97 - 0
Admin.NET/Admin.NET.Core/Entity/SysWechatRefund.cs

@@ -0,0 +1,97 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 系统微信支付退款表
+/// </summary>
+[SugarTable(null, "系统微信支付退款表")]
+[SysTable]
+[SugarIndex("idx_{table}_WechatPayId", nameof(WechatPayId), OrderByType.Asc)]
+public partial class SysWechatRefund : EntityBase
+{
+    /// <summary>
+    /// 定单主键
+    /// </summary>
+    [SugarColumn(ColumnDescription = "定单主键")]
+    public long WechatPayId { get; set; }
+
+    /// <summary>
+    /// 商户退款号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "商户退款号")]
+    [Required]
+    public virtual string OutRefundNumber { get; set; }
+
+    /// <summary>
+    /// 退款订单号
+    /// </summary>
+    [SugarColumn(ColumnDescription = "退款订单号")]
+    [Required]
+    public virtual string TransactionId { get; set; }
+
+    /// <summary>
+    /// 退款原因
+    /// </summary>
+    [SugarColumn(ColumnDescription = "退款原因")]
+    public string? Reason { get; set; }
+
+    /// <summary>
+    /// 退款渠道
+    /// </summary>
+    [SugarColumn(ColumnDescription = "退款渠道")]
+    public string? Channel { get; set; }
+
+    /// <summary>
+    /// 退款入账账户
+    /// </summary>
+    /// <remarks>
+    /// 取当前退款单的退款入账方,有以下几种情况:
+    /// 1)退回银行卡:{银行名称}{卡类型}{ 卡尾号}
+    /// 2)退回支付用户零钱: 支付用户零钱
+    /// 3)退还商户: 商户基本账户商户结算银行账户
+    /// 4)退回支付用户零钱通: 支付用户零钱通
+    /// </remarks>
+    [SugarColumn(ColumnDescription = "退款入账账户")]
+    public string? UserReceivedAccount { get; set; }
+
+    /// <summary>
+    /// 退款状态
+    /// </summary>
+    [SugarColumn(ColumnDescription = "退款状态")]
+    public string? TradeState { get; set; }
+
+    /// <summary>
+    /// 交易状态描述
+    /// </summary>
+    [SugarColumn(ColumnDescription = "交易状态描述")]
+    public string? TradeStateDescription { get; set; }
+
+    /// <summary>
+    /// 订单总金额
+    /// </summary>
+    [SugarColumn(ColumnDescription = "退款金额")]
+    public int Refund { get; set; }
+
+    /// <summary>
+    /// 支完成时间
+    /// </summary>
+    [SugarColumn(ColumnDescription = "完成时间")]
+    public DateTime? SuccessTime { get; set; }
+
+    /// <summary>
+    /// 回调通知地址
+    /// </summary>
+    [SugarColumn(ColumnDescription = "回调通知地址")]
+    public string? NotifyUrl { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    [SugarColumn(ColumnDescription = "备注")]
+    public string? Remark { get; set; }
+}

+ 15 - 3
Admin.NET/Admin.NET.Core/Enum/ErrorCodeEnum.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -205,6 +205,12 @@ public enum ErrorCodeEnum
     [ErrorCodeItemMetadata("新密码不能与旧密码相同")]
     D1028,
 
+    /// <summary>
+    /// 系统默认账号禁止删除
+    /// </summary>
+    [ErrorCodeItemMetadata("系统默认账号禁止删除")]
+    D1029,
+
     /// <summary>
     /// 父机构不存在
     /// </summary>
@@ -254,9 +260,9 @@ public enum ErrorCodeEnum
     D2007,
 
     /// <summary>
-    /// 租户默认机构禁止删除
+    /// 系统默认机构禁止删除
     /// </summary>
-    [ErrorCodeItemMetadata("租户默认机构禁止删除")]
+    [ErrorCodeItemMetadata("系统默认机构禁止删除")]
     D2008,
 
     /// <summary>
@@ -649,6 +655,12 @@ public enum ErrorCodeEnum
     [ErrorCodeItemMetadata("不允许添加相同字段名")]
     db1002,
 
+    /// <summary>
+    /// 实体文件不存在或匹配不到。如果是刚刚生成的实体,请重启服务后再试
+    /// </summary>
+    [ErrorCodeItemMetadata("实体文件不存在或匹配不到。如果是刚刚生成的实体,请重启服务后再试")]
+    db1003,
+
     /// <summary>
     /// 父节点不存在
     /// </summary>

+ 31 - 0
Admin.NET/Admin.NET.Core/EventBus/EventHandlerMonitor.cs

@@ -0,0 +1,31 @@
+// 麻省理工学院许可证
+//
+// 版权所有 (c) 2021-2023 zuohuaijun,大名科技(天津)有限公司  联系电话/微信:18020030720  QQ:515096995
+//
+// 特此免费授予获得本软件的任何人以处理本软件的权利,但须遵守以下条件:在所有副本或重要部分的软件中必须包括上述版权声明和本许可声明。
+//
+// 软件按“原样”提供,不提供任何形式的明示或暗示的保证,包括但不限于对适销性、适用性和非侵权的保证。
+// 在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是因合同、侵权或其他方式引起的,与软件或其使用或其他交易有关。
+
+namespace Admin.NET.Core;
+
+public class EventHandlerMonitor : IEventHandlerMonitor
+{
+    public Task OnExecutingAsync(EventHandlerExecutingContext context)
+    {
+        //_logger.LogInformation("执行之前:{EventId}", context.Source.EventId);
+        return Task.CompletedTask;
+    }
+
+    public Task OnExecutedAsync(EventHandlerExecutedContext context)
+    {
+        //_logger.LogInformation("执行之后:{EventId}", context.Source.EventId);
+
+        if (context.Exception != null)
+        {
+            Log.Error($"EventHandlerMonitor.OnExecutedAsync 执行出错啦:{context.Source.EventId}", context.Exception);
+        }
+
+        return Task.CompletedTask;
+    }
+}

+ 1 - 1
Admin.NET/Admin.NET.Core/EventBus/RedisQueue.cs

@@ -13,7 +13,7 @@ namespace Admin.NET.Core;
 /// </summary>
 public static class RedisQueue
 {
-    private static ICacheProvider _cacheProvider = App.GetService<ICacheProvider>();
+    private static ICacheProvider _cacheProvider = App.GetRequiredService<ICacheProvider>();
 
     /// <summary>创建Redis消息队列。默认消费一次,指定消费者group时使用STREAM结构,支持多消费组共享消息</summary>
     /// <remarks>

+ 43 - 21
Admin.NET/Admin.NET.Core/EventBus/RetryEventHandlerExecutor.cs

@@ -1,22 +1,44 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// 事件执行器-超时控制、失败重试熔断等等
-/// </summary>
-public class RetryEventHandlerExecutor : IEventHandlerExecutor
-{
-    public async Task ExecuteAsync(EventHandlerExecutingContext context, Func<EventHandlerExecutingContext, Task> handler)
-    {
-        // 如果执行失败,每隔 1s 重试,最多三次
-        await Retry.InvokeAsync(async () =>
-        {
-            await handler(context);
-        }, 3, 1000);
-    }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 事件执行器-超时控制、失败重试熔断等等
+/// </summary>
+public class RetryEventHandlerExecutor : IEventHandlerExecutor
+{
+    public async Task ExecuteAsync(EventHandlerExecutingContext context, Func<EventHandlerExecutingContext, Task> handler)
+    {
+        var eventSubscribeAttribute = context.Attribute;
+        // 判断是否自定义了重试失败回调服务
+        var fallbackPolicyService = eventSubscribeAttribute?.FallbackPolicy == null
+            ? null
+            : App.GetService(eventSubscribeAttribute.FallbackPolicy) as IEventFallbackPolicy;
+
+        await Retry.InvokeAsync(async () =>
+        {
+            try
+            {
+                await handler(context);
+            }
+            catch (Exception ex)
+            {
+                Log.Error($"Invoke EventHandler {context.Source.EventId} Error", ex);
+                throw;
+            }
+        }
+        , eventSubscribeAttribute?.NumRetries ?? 0
+        , eventSubscribeAttribute?.RetryTimeout ?? 1000
+        , exceptionTypes: eventSubscribeAttribute?.ExceptionTypes
+        , fallbackPolicy: fallbackPolicyService == null ? null : async (Exception ex) => { await fallbackPolicyService.CallbackAsync(context, ex); }
+        , retryAction: (total, times) =>
+        {
+            // 输出重试日志
+            Log.Warning($"Retrying {times}/{total} times for  EventHandler {context.Source.EventId}");
+        });
+    }
 }

+ 0 - 41
Admin.NET/Admin.NET.Core/Extension/HttpContextExtension.cs

@@ -1,41 +0,0 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-using System.Net;
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// HttpContext拓展
-/// </summary>
-[SuppressSniffer]
-public static partial class HttpContextExtension
-{
-    /// <summary>
-    /// 获取客户端真实 IP 地址
-    /// </summary>
-    /// <returns>bool</returns>
-    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;
-    }
-}

+ 1 - 1
Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

@@ -160,7 +160,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
             }
 
             // 记录操作日志
-            if (!(await _sysConfigService.GetConfigValue<bool>(CommonConst.SysOpLog))) return;
+            if (!await _sysConfigService.GetConfigValue<bool>(CommonConst.SysOpLog)) return;
             await _db.Insertable(new SysLogOp
             {
                 ControllerName = loggingMonitor.controllerName,

+ 205 - 197
Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs

@@ -1,198 +1,206 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Core;
-
-/// <summary>
-/// 系统菜单表种子数据
-/// </summary>
-public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
-{
-    /// <summary>
-    /// 种子数据
-    /// </summary>
-    /// <returns></returns>
-    public IEnumerable<SysMenu> HasData()
-    {
-        return new[]
-        {
-            new SysMenu{ Id=1300000000101, Pid=0, Title="工作台", Path="/dashboard", Name="dashboard", Component="Layout", Icon="ele-HomeFilled", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=0 },
-            new SysMenu{ Id=1300000000111, Pid=1300000000101, Title="工作台", Path="/dashboard/home", Name="home", Component="/home/index", IsAffix=true, Icon="ele-HomeFilled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1300000000121, Pid=1300000000101, Title="站内信", Path="/dashboard/notice", Name="notice", Component="/home/notice/index", Icon="ele-Bell", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=101 },
-
-            // 建议此处Id范围之间放置具体业务应用菜单
-
-            new SysMenu{ Id=1310000000101, Pid=0, Title="系统管理", Path="/system", Name="system", Component="Layout", Icon="ele-Setting", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=10000 },
-
-            new SysMenu{ Id=1310000000111, Pid=1310000000101, Title="账号管理", Path="/system/user", Name="sysUser", Component="/system/user/index", Icon="ele-User", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000112, Pid=1310000000111, Title="查询", Permission="sysUser:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000113, Pid=1310000000111, Title="编辑", Permission="sysUser:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000114, Pid=1310000000111, Title="增加", Permission="sysUser:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000115, Pid=1310000000111, Title="删除", Permission="sysUser:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000116, Pid=1310000000111, Title="详情", Permission="sysUser:detail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000117, Pid=1310000000111, Title="授权角色", Permission="sysUser:grantRole", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000118, Pid=1310000000111, Title="重置密码", Permission="sysUser:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000119, Pid=1310000000111, Title="设置状态", Permission="sysUser:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000120, Pid=1310000000111, Title="强制下线", Permission="sysOnlineUser:forceOffline", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000121, Pid=1310000000111, Title="解除锁定", Permission="sysUser:unlockLogin", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000131, Pid=1310000000101, Title="角色管理", Path="/system/role", Name="sysRole", Component="/system/role/index", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000132, Pid=1310000000131, Title="查询", Permission="sysRole:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000133, Pid=1310000000131, Title="编辑", Permission="sysRole:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000134, Pid=1310000000131, Title="增加", Permission="sysRole:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000135, Pid=1310000000131, Title="删除", Permission="sysRole:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000136, Pid=1310000000131, Title="授权菜单", Permission="sysRole:grantMenu", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000137, Pid=1310000000131, Title="授权数据", Permission="sysRole:grantDataScope", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000138, Pid=1310000000131, Title="设置状态", Permission="sysRole:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000141, Pid=1310000000101, Title="机构管理", Path="/system/org", Name="sysOrg", Component="/system/org/index", Icon="ele-OfficeBuilding", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            //new SysMenu{ Id=1310000000142, Pid=1310000000141, Title="查询", Permission="sysOrg:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000143, Pid=1310000000141, Title="编辑", Permission="sysOrg:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000144, Pid=1310000000141, Title="增加", Permission="sysOrg:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000145, Pid=1310000000141, Title="删除", Permission="sysOrg:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000151, Pid=1310000000101, Title="职位管理", Path="/system/pos", Name="sysPos", Component="/system/pos/index",Icon="ele-Mug", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-            new SysMenu{ Id=1310000000152, Pid=1310000000151, Title="查询", Permission="sysPos:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000153, Pid=1310000000151, Title="编辑", Permission="sysPos:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000154, Pid=1310000000151, Title="增加", Permission="sysPos:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000155, Pid=1310000000151, Title="删除", Permission="sysPos:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000161, Pid=1310000000101, Title="个人中心", Path="/system/userCenter", Name="sysUserCenter", Component="/system/user/component/userCenter",Icon="ele-Medal", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
-            new SysMenu{ Id=1310000000162, Pid=1310000000161, Title="修改密码", Permission="sysUser:changePwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000163, Pid=1310000000161, Title="基本信息", Permission="sysUser:baseInfo", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000164, Pid=1310000000161, Title="电子签名", Permission="sysFile:uploadSignature", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000165, Pid=1310000000161, Title="上传头像", Permission="sysFile:uploadAvatar", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000171, Pid=1310000000101, Title="通知公告", Path="/system/notice", Name="sysNotice", Component="/system/notice/index",Icon="ele-Bell", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
-            new SysMenu{ Id=1310000000172, Pid=1310000000171, Title="查询", Permission="sysNotice:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000173, Pid=1310000000171, Title="编辑", Permission="sysNotice:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000174, Pid=1310000000171, Title="增加", Permission="sysNotice:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000175, Pid=1310000000171, Title="删除", Permission="sysNotice:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000176, Pid=1310000000171, Title="发布", Permission="sysNotice:public", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000177, Pid=1310000000171, Title="撤回", Permission="sysNotice:cancel", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000181, Pid=1310000000101, Title="三方账号", Path="/system/weChatUser", Name="sysWechatUser", Component="/system/weChatUser/index",Icon="ele-ChatDotRound", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
-            new SysMenu{ Id=1310000000182, Pid=1310000000181, Title="查询", Permission="sysWechatUser:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000183, Pid=1310000000181, Title="编辑", Permission="sysWechatUser:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000184, Pid=1310000000181, Title="增加", Permission="sysWechatUser:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000185, Pid=1310000000181, Title="删除", Permission="sysWechatUser:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000191, Pid=1310000000101, Title="AD域配置", Path="/system/ldap", Name="sysLdap", Component="/system/ldap/index",Icon="ele-Place", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=170 },
-            new SysMenu{ Id=1310000000192, Pid=1310000000191, Title="查询", Permission="sysLdap:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000193, Pid=1310000000191, Title="详情", Permission="sysLdap:detail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000194, Pid=1310000000191, Title="编辑", Permission="sysLdap:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            new SysMenu{ Id=1310000000195, Pid=1310000000191, Title="增加", Permission="sysLdap:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-            new SysMenu{ Id=1310000000196, Pid=1310000000191, Title="删除", Permission="sysLdap:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
-            new SysMenu{ Id=1310000000197, Pid=1310000000191, Title="同步域账户", Permission="sysLdap:syncUser", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
-            new SysMenu{ Id=1310000000198, Pid=1310000000191, Title="同步域组织", Permission="sysLdap:syncOrg", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
-
-            new SysMenu{ Id=1310000000301, Pid=0, Title="平台管理", Path="/platform", Name="platform", Component="Layout", Icon="ele-Menu", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=11000 },
-
-            new SysMenu{ Id=1310000000311, Pid=1310000000301, Title="租户管理", Path="/platform/tenant", Name="sysTenant", Component="/system/tenant/index", Icon="ele-School", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000312, Pid=1310000000311, Title="查询", Permission="sysTenant:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000313, Pid=1310000000311, Title="编辑", Permission="sysTenant:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000314, Pid=1310000000311, Title="增加", Permission="sysTenant:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000315, Pid=1310000000311, Title="删除", Permission="sysTenant:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000316, Pid=1310000000311, Title="授权菜单", Permission="sysTenant:grantMenu", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000317, Pid=1310000000311, Title="重置密码", Permission="sysTenant:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000318, Pid=1310000000311, Title="生成库", Permission="sysTenant:createDb", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000319, Pid=1310000000311, Title="设置状态", Permission="sysTenant:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000321, Pid=1310000000301, Title="菜单管理", Path="/platform/menu", Name="sysMenu", Component="/system/menu/index", Icon="ele-Menu", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000322, Pid=1310000000321, Title="查询", Permission="sysMenu:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000323, Pid=1310000000321, Title="编辑", Permission="sysMenu:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000324, Pid=1310000000321, Title="增加", Permission="sysMenu:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000325, Pid=1310000000321, Title="删除", Permission="sysMenu:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000331, Pid=1310000000301, Title="参数配置", Path="/platform/config", Name="sysConfig", Component="/system/config/index", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            new SysMenu{ Id=1310000000332, Pid=1310000000331, Title="查询", Permission="sysConfig:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000333, Pid=1310000000331, Title="编辑", Permission="sysConfig:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000334, Pid=1310000000331, Title="增加", Permission="sysConfig:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000335, Pid=1310000000331, Title="删除", Permission="sysConfig:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000341, Pid=1310000000301, Title="字典管理", Path="/platform/dict", Name="sysDict", Component="/system/dict/index", Icon="ele-Collection", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-            new SysMenu{ Id=1310000000342, Pid=1310000000341, Title="查询", Permission="sysDictType:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000343, Pid=1310000000341, Title="编辑", Permission="sysDictType:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000344, Pid=1310000000341, Title="增加", Permission="sysDictType:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000345, Pid=1310000000341, Title="删除", Permission="sysDictType:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000351, Pid=1310000000301, Title="任务调度", Path="/platform/job", Name="sysJob", Component="/system/job/index", Icon="ele-AlarmClock", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
-            new SysMenu{ Id=1310000000352, Pid=1310000000351, Title="查询", Permission="sysJob:pageJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000353, Pid=1310000000351, Title="编辑", Permission="sysJob:updateJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000354, Pid=1310000000351, Title="增加", Permission="sysJob:addJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000355, Pid=1310000000351, Title="删除", Permission="sysJob:deleteJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000361, Pid=1310000000301, Title="系统监控", Path="/platform/server", Name="sysServer", Component="/system/server/index", Icon="ele-Monitor", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
-
-            new SysMenu{ Id=1310000000371, Pid=1310000000301, Title="缓存管理", Path="/platform/cache", Name="sysCache", Component="/system/cache/index", Icon="ele-Loading", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
-            new SysMenu{ Id=1310000000372, Pid=1310000000371, Title="查询", Permission="sysCache:keyList", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000373, Pid=1310000000371, Title="删除", Permission="sysCache:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000381, Pid=1310000000301, Title="行政区域", Path="/platform/region", Name="sysRegion", Component="/system/region/index", Icon="ele-LocationInformation", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=170 },
-            new SysMenu{ Id=1310000000382, Pid=1310000000381, Title="查询", Permission="sysRegion:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000383, Pid=1310000000381, Title="编辑", Permission="sysRegion:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000384, Pid=1310000000381, Title="增加", Permission="sysRegion:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000385, Pid=1310000000381, Title="删除", Permission="sysRegion:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000386, Pid=1310000000381, Title="同步", Permission="sysRegion:sync", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000391, Pid=1310000000301, Title="文件管理", Path="/platform/file", Name="sysFile", Component="/system/file/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=180 },
-            new SysMenu{ Id=1310000000392, Pid=1310000000391, Title="查询", Permission="sysFile:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000393, Pid=1310000000391, Title="上传", Permission="sysFile:uploadFile", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000394, Pid=1310000000391, Title="下载", Permission="sysFile:downloadFile", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000395, Pid=1310000000391, Title="删除", Permission="sysFile:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000396, Pid=1310000000391, Title="编辑", Permission="sysFile:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2023-10-27 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000401, Pid=1310000000301, Title="打印模板", Path="/platform/print", Name="sysPrint", Component="/system/print/index", Icon="ele-Printer", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=190 },
-            new SysMenu{ Id=1310000000402, Pid=1310000000401, Title="查询", Permission="sysPrint:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000403, Pid=1310000000401, Title="编辑", Permission="sysPrint:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000404, Pid=1310000000401, Title="增加", Permission="sysPrint:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000405, Pid=1310000000401, Title="删除", Permission="sysPrint:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000411, Pid=1310000000301, Title="动态插件", Path="/platform/plugin", Name="sysPlugin", Component="/system/plugin/index", Icon="ele-Connection", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=200 },
-            new SysMenu{ Id=1310000000412, Pid=1310000000411, Title="查询", Permission="sysPlugin:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000413, Pid=1310000000411, Title="编辑", Permission="sysPlugin:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000414, Pid=1310000000411, Title="增加", Permission="sysPlugin:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000415, Pid=1310000000411, Title="删除", Permission="sysPlugin:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000421, Pid=1310000000301, Title="开放接口", Path="/platform/openAccess", Name="sysOpenAccess", Component="/system/openAccess/index", Icon="ele-Link", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=210 },
-            new SysMenu{ Id=1310000000422, Pid=1310000000421, Title="查询", Permission="sysOpenAccess:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000423, Pid=1310000000421, Title="编辑", Permission="sysOpenAccess:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000424, Pid=1310000000421, Title="增加", Permission="sysOpenAccess:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000425, Pid=1310000000421, Title="删除", Permission="sysOpenAccess:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            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=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 },
-            new SysMenu{ Id=1310000000513, Pid=1310000000511, Title="清空", Permission="sysVislog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000521, Pid=1310000000501, Title="操作日志", Path="/log/oplog", Name="sysOpLog", Component="/system/log/oplog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000522, Pid=1310000000521, Title="查询", Permission="sysOplog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000523, Pid=1310000000521, Title="清空", Permission="sysOplog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000524, Pid=1310000000521, Title="导出", Permission="sysOplog:export", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000531, Pid=1310000000501, Title="异常日志", Path="/log/exlog", Name="sysExLog", Component="/system/log/exlog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            new SysMenu{ Id=1310000000532, Pid=1310000000531, Title="查询", Permission="sysExlog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000533, Pid=1310000000531, Title="清空", Permission="sysExlog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000534, Pid=1310000000531, Title="导出", Permission="sysExlog:export", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000541, Pid=1310000000501, Title="差异日志", Path="/log/difflog", Name="sysDiffLog", Component="/system/log/difflog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-            new SysMenu{ Id=1310000000542, Pid=1310000000541, Title="查询", Permission="sysDifflog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000543, Pid=1310000000541, Title="清空", Permission="sysDifflog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-
-            new SysMenu{ Id=1310000000601, Pid=0, Title="开发工具", Path="/develop", Name="develop", Component="Layout", Icon="ele-Cpu", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=13000 },
-            new SysMenu{ Id=1310000000611, Pid=1310000000601, Title="库表管理", Path="/develop/database", Name="sysDatabase", Component="/system/database/index",Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000621, Pid=1310000000601, Title="代码生成", Path="/develop/codeGen", Name="sysCodeGen", Component="/system/codeGen/index", Icon="ele-Crop", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000631, Pid=1310000000601, Title="表单设计", Path="/develop/formDes", Name="sysFormDes", Component="/system/formDes/index", Icon="ele-Edit", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-            new SysMenu{ Id=1310000000641, Pid=1310000000601, Title="系统接口", Path="/develop/api", Name="sysApi", Component="layout/routerView/iframe", IsIframe=true, OutLink="http://localhost:5005", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
-
-            new SysMenu{ Id=1310000000701, Pid=0, Title="帮助文档", Path="/doc", Name="doc", Component="Layout", Icon="ele-Notebook", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=14000 },
-            new SysMenu{ Id=1310000000711, Pid=1310000000701, Title="后台教程", Path="/doc/furion", Name="sysFurion", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://furion.baiqian.ltd/", Icon="ele-Promotion", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
-            new SysMenu{ Id=1310000000712, Pid=1310000000701, Title="前端教程", Path="/doc/element", Name="sysElement", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://element-plus.gitee.io/zh-CN/", Icon="ele-Position", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
-            new SysMenu{ Id=1310000000713, Pid=1310000000701, Title="SqlSugar", Path="/doc/SqlSugar", Name="sysSqlSugar", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://www.donet5.com/Home/Doc", Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
-
-            new SysMenu{ Id=1310000000801, Pid=0, Title="关于项目", Path="/about", Name="about", Component="/about/index", Icon="ele-InfoFilled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2023-03-12 00:00:00"), OrderNo=15000 },
-        };
-    }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 系统菜单表种子数据
+/// </summary>
+public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
+{
+    /// <summary>
+    /// 种子数据
+    /// </summary>
+    /// <returns></returns>
+    public IEnumerable<SysMenu> HasData()
+    {
+        return new[]
+        {
+            new SysMenu{ Id=1300000000101, Pid=0, Title="工作台", Path="/dashboard", Name="dashboard", Component="Layout", Icon="ele-HomeFilled", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=0 },
+            new SysMenu{ Id=1300000000111, Pid=1300000000101, Title="工作台", Path="/dashboard/home", Name="home", Component="/home/index", IsAffix=true, Icon="ele-HomeFilled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1300000000121, Pid=1300000000101, Title="站内信", Path="/dashboard/notice", Name="notice", Component="/home/notice/index", Icon="ele-Bell", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=101 },
+
+            // 建议此处Id范围之间放置具体业务应用菜单
+
+            new SysMenu{ Id=1310000000101, Pid=0, Title="系统管理", Path="/system", Name="system", Component="Layout", Icon="ele-Setting", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=10000 },
+
+            new SysMenu{ Id=1310000000111, Pid=1310000000101, Title="账号管理", Path="/system/user", Name="sysUser", Component="/system/user/index", Icon="ele-User", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000112, Pid=1310000000111, Title="查询", Permission="sysUser:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000113, Pid=1310000000111, Title="编辑", Permission="sysUser:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000114, Pid=1310000000111, Title="增加", Permission="sysUser:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000115, Pid=1310000000111, Title="删除", Permission="sysUser:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000116, Pid=1310000000111, Title="详情", Permission="sysUser:detail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000117, Pid=1310000000111, Title="授权角色", Permission="sysUser:grantRole", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000118, Pid=1310000000111, Title="重置密码", Permission="sysUser:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000119, Pid=1310000000111, Title="设置状态", Permission="sysUser:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000120, Pid=1310000000111, Title="强制下线", Permission="sysOnlineUser:forceOffline", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000121, Pid=1310000000111, Title="解除锁定", Permission="sysUser:unlockLogin", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000131, Pid=1310000000101, Title="角色管理", Path="/system/role", Name="sysRole", Component="/system/role/index", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000132, Pid=1310000000131, Title="查询", Permission="sysRole:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000133, Pid=1310000000131, Title="编辑", Permission="sysRole:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000134, Pid=1310000000131, Title="增加", Permission="sysRole:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000135, Pid=1310000000131, Title="删除", Permission="sysRole:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000136, Pid=1310000000131, Title="授权菜单", Permission="sysRole:grantMenu", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000137, Pid=1310000000131, Title="授权数据", Permission="sysRole:grantDataScope", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000138, Pid=1310000000131, Title="设置状态", Permission="sysRole:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000141, Pid=1310000000101, Title="机构管理", Path="/system/org", Name="sysOrg", Component="/system/org/index", Icon="ele-OfficeBuilding", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            //new SysMenu{ Id=1310000000142, Pid=1310000000141, Title="查询", Permission="sysOrg:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000143, Pid=1310000000141, Title="编辑", Permission="sysOrg:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000144, Pid=1310000000141, Title="增加", Permission="sysOrg:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000145, Pid=1310000000141, Title="删除", Permission="sysOrg:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000151, Pid=1310000000101, Title="职位管理", Path="/system/pos", Name="sysPos", Component="/system/pos/index",Icon="ele-Mug", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000152, Pid=1310000000151, Title="查询", Permission="sysPos:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000153, Pid=1310000000151, Title="编辑", Permission="sysPos:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000154, Pid=1310000000151, Title="增加", Permission="sysPos:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000155, Pid=1310000000151, Title="删除", Permission="sysPos:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000161, Pid=1310000000101, Title="个人中心", Path="/system/userCenter", Name="sysUserCenter", Component="/system/user/component/userCenter",Icon="ele-Medal", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
+            new SysMenu{ Id=1310000000162, Pid=1310000000161, Title="修改密码", Permission="sysUser:changePwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000163, Pid=1310000000161, Title="基本信息", Permission="sysUser:baseInfo", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000164, Pid=1310000000161, Title="电子签名", Permission="sysFile:uploadSignature", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000165, Pid=1310000000161, Title="上传头像", Permission="sysFile:uploadAvatar", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000171, Pid=1310000000101, Title="通知公告", Path="/system/notice", Name="sysNotice", Component="/system/notice/index",Icon="ele-Bell", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
+            new SysMenu{ Id=1310000000172, Pid=1310000000171, Title="查询", Permission="sysNotice:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000173, Pid=1310000000171, Title="编辑", Permission="sysNotice:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000174, Pid=1310000000171, Title="增加", Permission="sysNotice:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000175, Pid=1310000000171, Title="删除", Permission="sysNotice:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000176, Pid=1310000000171, Title="发布", Permission="sysNotice:public", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000177, Pid=1310000000171, Title="撤回", Permission="sysNotice:cancel", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000181, Pid=1310000000101, Title="三方账号", Path="/system/weChatUser", Name="sysWechatUser", Component="/system/weChatUser/index",Icon="ele-ChatDotRound", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
+            new SysMenu{ Id=1310000000182, Pid=1310000000181, Title="查询", Permission="sysWechatUser:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000183, Pid=1310000000181, Title="编辑", Permission="sysWechatUser:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000184, Pid=1310000000181, Title="增加", Permission="sysWechatUser:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000185, Pid=1310000000181, Title="删除", Permission="sysWechatUser:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000191, Pid=1310000000101, Title="AD域配置", Path="/system/ldap", Name="sysLdap", Component="/system/ldap/index",Icon="ele-Place", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=170 },
+            new SysMenu{ Id=1310000000192, Pid=1310000000191, Title="查询", Permission="sysLdap:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000193, Pid=1310000000191, Title="详情", Permission="sysLdap:detail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000194, Pid=1310000000191, Title="编辑", Permission="sysLdap:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000195, Pid=1310000000191, Title="增加", Permission="sysLdap:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000196, Pid=1310000000191, Title="删除", Permission="sysLdap:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
+            new SysMenu{ Id=1310000000197, Pid=1310000000191, Title="同步域账户", Permission="sysLdap:syncUser", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
+            new SysMenu{ Id=1310000000198, Pid=1310000000191, Title="同步域组织", Permission="sysLdap:syncOrg", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
+
+            new SysMenu{ Id=1310000000301, Pid=0, Title="平台管理", Path="/platform", Name="platform", Component="Layout", Icon="ele-Menu", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=11000 },
+
+            new SysMenu{ Id=1310000000311, Pid=1310000000301, Title="租户管理", Path="/platform/tenant", Name="sysTenant", Component="/system/tenant/index", Icon="ele-School", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000312, Pid=1310000000311, Title="查询", Permission="sysTenant:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000313, Pid=1310000000311, Title="编辑", Permission="sysTenant:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000314, Pid=1310000000311, Title="增加", Permission="sysTenant:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000315, Pid=1310000000311, Title="删除", Permission="sysTenant:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000316, Pid=1310000000311, Title="授权菜单", Permission="sysTenant:grantMenu", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000317, Pid=1310000000311, Title="重置密码", Permission="sysTenant:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000318, Pid=1310000000311, Title="生成库", Permission="sysTenant:createDb", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000319, Pid=1310000000311, Title="设置状态", Permission="sysTenant:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000321, Pid=1310000000301, Title="菜单管理", Path="/platform/menu", Name="sysMenu", Component="/system/menu/index", Icon="ele-Menu", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000322, Pid=1310000000321, Title="查询", Permission="sysMenu:list", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000323, Pid=1310000000321, Title="编辑", Permission="sysMenu:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000324, Pid=1310000000321, Title="增加", Permission="sysMenu:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000325, Pid=1310000000321, Title="删除", Permission="sysMenu:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000331, Pid=1310000000301, Title="参数配置", Path="/platform/config", Name="sysConfig", Component="/system/config/index", Icon="ele-DocumentCopy", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000332, Pid=1310000000331, Title="查询", Permission="sysConfig:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000333, Pid=1310000000331, Title="编辑", Permission="sysConfig:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000334, Pid=1310000000331, Title="增加", Permission="sysConfig:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000335, Pid=1310000000331, Title="删除", Permission="sysConfig:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000341, Pid=1310000000301, Title="字典管理", Path="/platform/dict", Name="sysDict", Component="/system/dict/index", Icon="ele-Collection", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000342, Pid=1310000000341, Title="查询", Permission="sysDictType:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000343, Pid=1310000000341, Title="编辑", Permission="sysDictType:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000344, Pid=1310000000341, Title="增加", Permission="sysDictType:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000345, Pid=1310000000341, Title="删除", Permission="sysDictType:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000351, Pid=1310000000301, Title="任务调度", Path="/platform/job", Name="sysJob", Component="/system/job/index", Icon="ele-AlarmClock", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=140 },
+            new SysMenu{ Id=1310000000352, Pid=1310000000351, Title="查询", Permission="sysJob:pageJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000353, Pid=1310000000351, Title="编辑", Permission="sysJob:updateJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000354, Pid=1310000000351, Title="增加", Permission="sysJob:addJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000355, Pid=1310000000351, Title="删除", Permission="sysJob:deleteJobDetail", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000361, Pid=1310000000301, Title="系统监控", Path="/platform/server", Name="sysServer", Component="/system/server/index", Icon="ele-Monitor", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=150 },
+
+            new SysMenu{ Id=1310000000371, Pid=1310000000301, Title="缓存管理", Path="/platform/cache", Name="sysCache", Component="/system/cache/index", Icon="ele-Loading", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=160 },
+            new SysMenu{ Id=1310000000372, Pid=1310000000371, Title="查询", Permission="sysCache:keyList", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000373, Pid=1310000000371, Title="删除", Permission="sysCache:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000381, Pid=1310000000301, Title="行政区域", Path="/platform/region", Name="sysRegion", Component="/system/region/index", Icon="ele-LocationInformation", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=170 },
+            new SysMenu{ Id=1310000000382, Pid=1310000000381, Title="查询", Permission="sysRegion:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000383, Pid=1310000000381, Title="编辑", Permission="sysRegion:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000384, Pid=1310000000381, Title="增加", Permission="sysRegion:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000385, Pid=1310000000381, Title="删除", Permission="sysRegion:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000386, Pid=1310000000381, Title="同步", Permission="sysRegion:sync", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000391, Pid=1310000000301, Title="文件管理", Path="/platform/file", Name="sysFile", Component="/system/file/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=180 },
+            new SysMenu{ Id=1310000000392, Pid=1310000000391, Title="查询", Permission="sysFile:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000393, Pid=1310000000391, Title="上传", Permission="sysFile:uploadFile", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000394, Pid=1310000000391, Title="下载", Permission="sysFile:downloadFile", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000395, Pid=1310000000391, Title="删除", Permission="sysFile:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000396, Pid=1310000000391, Title="编辑", Permission="sysFile:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2023-10-27 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000401, Pid=1310000000301, Title="打印模板", Path="/platform/print", Name="sysPrint", Component="/system/print/index", Icon="ele-Printer", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=190 },
+            new SysMenu{ Id=1310000000402, Pid=1310000000401, Title="查询", Permission="sysPrint:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000403, Pid=1310000000401, Title="编辑", Permission="sysPrint:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000404, Pid=1310000000401, Title="增加", Permission="sysPrint:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000405, Pid=1310000000401, Title="删除", Permission="sysPrint:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000411, Pid=1310000000301, Title="动态插件", Path="/platform/plugin", Name="sysPlugin", Component="/system/plugin/index", Icon="ele-Connection", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=200 },
+            new SysMenu{ Id=1310000000412, Pid=1310000000411, Title="查询", Permission="sysPlugin:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000413, Pid=1310000000411, Title="编辑", Permission="sysPlugin:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000414, Pid=1310000000411, Title="增加", Permission="sysPlugin:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000415, Pid=1310000000411, Title="删除", Permission="sysPlugin:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000421, Pid=1310000000301, Title="开放接口", Path="/platform/openAccess", Name="sysOpenAccess", Component="/system/openAccess/index", Icon="ele-Link", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=210 },
+            new SysMenu{ Id=1310000000422, Pid=1310000000421, Title="查询", Permission="sysOpenAccess:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000423, Pid=1310000000421, Title="编辑", Permission="sysOpenAccess:update", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000424, Pid=1310000000421, Title="增加", Permission="sysOpenAccess:add", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000425, Pid=1310000000421, Title="删除", Permission="sysOpenAccess:delete", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            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 },
+            new SysMenu{ Id=1310000000513, Pid=1310000000511, Title="清空", Permission="sysVislog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000521, Pid=1310000000501, Title="操作日志", Path="/log/oplog", Name="sysOpLog", Component="/system/log/oplog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000522, Pid=1310000000521, Title="查询", Permission="sysOplog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000523, Pid=1310000000521, Title="清空", Permission="sysOplog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000524, Pid=1310000000521, Title="导出", Permission="sysOplog:export", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000531, Pid=1310000000501, Title="异常日志", Path="/log/exlog", Name="sysExLog", Component="/system/log/exlog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000532, Pid=1310000000531, Title="查询", Permission="sysExlog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000533, Pid=1310000000531, Title="清空", Permission="sysExlog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000534, Pid=1310000000531, Title="导出", Permission="sysExlog:export", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000541, Pid=1310000000501, Title="差异日志", Path="/log/difflog", Name="sysDiffLog", Component="/system/log/difflog/index", Icon="ele-Document", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+            new SysMenu{ Id=1310000000542, Pid=1310000000541, Title="查询", Permission="sysDifflog:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000543, Pid=1310000000541, Title="清空", Permission="sysDifflog:clear", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+
+            new SysMenu{ Id=1310000000601, Pid=0, Title="开发工具", Path="/develop", Name="develop", Component="Layout", Icon="ele-Cpu", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=13000 },
+            new SysMenu{ Id=1310000000611, Pid=1310000000601, Title="库表管理", Path="/develop/database", Name="sysDatabase", Component="/system/database/index",Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000621, Pid=1310000000601, Title="代码生成", Path="/develop/codeGen", Name="sysCodeGen", Component="/system/codeGen/index", Icon="ele-Crop", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000631, Pid=1310000000601, Title="表单设计", Path="/develop/formDes", Name="sysFormDes", Component="/system/formDes/index", Icon="ele-Edit", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000641, Pid=1310000000601, Title="系统接口", Path="/develop/api", Name="sysApi", Component="layout/routerView/iframe", IsIframe=true, OutLink="http://localhost:5005", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+
+            new SysMenu{ Id=1310000000701, Pid=0, Title="帮助文档", Path="/doc", Name="doc", Component="Layout", Icon="ele-Notebook", Type=MenuTypeEnum.Dir, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=14000 },
+            new SysMenu{ Id=1310000000711, Pid=1310000000701, Title="框架教程", Path="/doc/admin", Name="sysAdmin", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="http://101.43.53.74:5050/", Icon="ele-Sunny", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000712, Pid=1310000000701, Title="后台教程", Path="/doc/furion", Name="sysFurion", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://furion.baiqian.ltd/", Icon="ele-Promotion", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
+            new SysMenu{ Id=1310000000713, Pid=1310000000701, Title="前端教程", Path="/doc/element", Name="sysElement", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://element-plus.gitee.io/zh-CN/", Icon="ele-Position", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=120 },
+            new SysMenu{ Id=1310000000714, Pid=1310000000701, Title="SqlSugar", Path="/doc/SqlSugar", Name="sysSqlSugar", Component="layout/routerView/link", IsIframe=false, IsKeepAlive=false, OutLink="https://www.donet5.com/Home/Doc", Icon="ele-Coin", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=130 },
+
+            new SysMenu{ Id=1310000000801, Pid=0, Title="关于项目", Path="/about", Name="about", Component="/about/index", Icon="ele-InfoFilled", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2023-03-12 00:00:00"), OrderNo=15000 },
+        };
+    }
 }

+ 2 - 2
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);
@@ -277,7 +277,7 @@ public class SysAuthService : IDynamicApiController, ITransient
         // 获取水印文字(若系统水印为空则全局为空)
         var watermarkText = await _sysConfigService.GetConfigValue<string>("sys_web_watermark");
         if (!string.IsNullOrWhiteSpace(watermarkText))
-            watermarkText += $"-{user.RealName}-{_httpContextAccessor.HttpContext.GetRemoteIp()}-{DateTime.Now}";
+            watermarkText += $"-{user.RealName}"; // $"-{user.RealName}-{_httpContextAccessor.HttpContext.GetRemoteIpAddressToIPv4(true)}-{DateTime.Now}";
         return new LoginUserOutput
         {
             Id = user.Id,

+ 23 - 23
Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs

@@ -14,12 +14,12 @@ namespace Admin.NET.Core.Service;
 [ApiDescriptionSettings(Order = 400)]
 public class SysCacheService : IDynamicApiController, ISingleton
 {
-    private readonly ICache _cache;
+    private static ICacheProvider _cacheProvider;
     private readonly CacheOptions _cacheOptions;
 
-    public SysCacheService(ICache cache, IOptions<CacheOptions> cacheOptions)
+    public SysCacheService(ICacheProvider cacheProvider, IOptions<CacheOptions> cacheOptions)
     {
-        _cache = cache;
+        _cacheProvider = cacheProvider;
         _cacheOptions = cacheOptions.Value;
     }
 
@@ -30,9 +30,9 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [DisplayName("获取缓存键名集合")]
     public List<string> GetKeyList()
     {
-        return _cache == Cache.Default
-            ? _cache.Keys.Where(u => u.StartsWith(_cacheOptions.Prefix)).Select(u => u[_cacheOptions.Prefix.Length..]).OrderBy(u => u).ToList()
-            : ((FullRedis)_cache).Search($"{_cacheOptions.Prefix}*", int.MaxValue).Select(u => u[_cacheOptions.Prefix.Length..]).OrderBy(u => u).ToList();
+        return _cacheProvider.Cache == Cache.Default
+            ? _cacheProvider.Cache.Keys.Where(u => u.StartsWith(_cacheOptions.Prefix)).Select(u => u[_cacheOptions.Prefix.Length..]).OrderBy(u => u).ToList()
+            : ((FullRedis)_cacheProvider.Cache).Search($"{_cacheOptions.Prefix}*", int.MaxValue).Select(u => u[_cacheOptions.Prefix.Length..]).OrderBy(u => u).ToList();
     }
 
     /// <summary>
@@ -45,7 +45,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     public bool Set(string key, object value)
     {
         if (string.IsNullOrWhiteSpace(key)) return false;
-        return _cache.Set($"{_cacheOptions.Prefix}{key}", value);
+        return _cacheProvider.Cache.Set($"{_cacheOptions.Prefix}{key}", value);
     }
 
     /// <summary>
@@ -59,7 +59,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     public bool Set(string key, object value, TimeSpan expire)
     {
         if (string.IsNullOrWhiteSpace(key)) return false;
-        return _cache.Set($"{_cacheOptions.Prefix}{key}", value, expire);
+        return _cacheProvider.Cache.Set($"{_cacheOptions.Prefix}{key}", value, expire);
     }
 
     /// <summary>
@@ -71,7 +71,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [NonAction]
     public T Get<T>(string key)
     {
-        return _cache.Get<T>($"{_cacheOptions.Prefix}{key}");
+        return _cacheProvider.Cache.Get<T>($"{_cacheOptions.Prefix}{key}");
     }
 
     /// <summary>
@@ -83,7 +83,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [DisplayName("删除缓存")]
     public int Remove(string key)
     {
-        return _cache.Remove($"{_cacheOptions.Prefix}{key}");
+        return _cacheProvider.Cache.Remove($"{_cacheOptions.Prefix}{key}");
     }
 
     /// <summary>
@@ -94,7 +94,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [NonAction]
     public bool ExistKey(string key)
     {
-        return _cache.ContainsKey($"{_cacheOptions.Prefix}{key}");
+        return _cacheProvider.Cache.ContainsKey($"{_cacheOptions.Prefix}{key}");
     }
 
     /// <summary>
@@ -106,10 +106,10 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [DisplayName("根据键名前缀删除缓存")]
     public int RemoveByPrefixKey(string prefixKey)
     {
-        var delKeys = _cache == Cache.Default
-            ? _cache.Keys.Where(u => u.StartsWith($"{_cacheOptions.Prefix}{prefixKey}")).ToArray()
-            : ((FullRedis)_cache).Search($"{_cacheOptions.Prefix}{prefixKey}*", int.MaxValue).ToArray();
-        return _cache.Remove(delKeys);
+        var delKeys = _cacheProvider.Cache == Cache.Default
+            ? _cacheProvider.Cache.Keys.Where(u => u.StartsWith($"{_cacheOptions.Prefix}{prefixKey}")).ToArray()
+            : ((FullRedis)_cacheProvider.Cache).Search($"{_cacheOptions.Prefix}{prefixKey}*", int.MaxValue).ToArray();
+        return _cacheProvider.Cache.Remove(delKeys);
     }
 
     /// <summary>
@@ -120,9 +120,9 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [DisplayName("根据键名前缀获取键名集合")]
     public List<string> GetKeysByPrefixKey(string prefixKey)
     {
-        return _cache == Cache.Default
-            ? _cache.Keys.Where(u => u.StartsWith($"{_cacheOptions.Prefix}{prefixKey}")).Select(u => u[_cacheOptions.Prefix.Length..]).ToList()
-            : ((FullRedis)_cache).Search($"{_cacheOptions.Prefix}{prefixKey}*", int.MaxValue).Select(u => u[_cacheOptions.Prefix.Length..]).ToList();
+        return _cacheProvider.Cache == Cache.Default
+            ? _cacheProvider.Cache.Keys.Where(u => u.StartsWith($"{_cacheOptions.Prefix}{prefixKey}")).Select(u => u[_cacheOptions.Prefix.Length..]).ToList()
+            : ((FullRedis)_cacheProvider.Cache).Search($"{_cacheOptions.Prefix}{prefixKey}*", int.MaxValue).Select(u => u[_cacheOptions.Prefix.Length..]).ToList();
     }
 
     /// <summary>
@@ -133,9 +133,9 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [DisplayName("获取缓存值")]
     public object GetValue(string key)
     {
-        return _cache == Cache.Default
-            ? _cache.Get<object>($"{_cacheOptions.Prefix}{key}")
-            : _cache.Get<string>($"{_cacheOptions.Prefix}{key}");
+        return _cacheProvider.Cache == Cache.Default
+            ? _cacheProvider.Cache.Get<object>($"{_cacheOptions.Prefix}{key}")
+            : _cacheProvider.Cache.Get<string>($"{_cacheOptions.Prefix}{key}");
     }
 
     /// <summary>
@@ -150,7 +150,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     public T GetOrAdd<T>(string key, Func<string, T> callback, int expire = -1)
     {
         if (string.IsNullOrWhiteSpace(key)) return default;
-        return _cache.GetOrAdd($"{_cacheOptions.Prefix}{key}", callback, expire);
+        return _cacheProvider.Cache.GetOrAdd($"{_cacheOptions.Prefix}{key}", callback, expire);
     }
 
     /// <summary>
@@ -162,7 +162,7 @@ public class SysCacheService : IDynamicApiController, ISingleton
     [NonAction]
     public RedisHash<string, T> GetHashMap<T>(string key)
     {
-        return _cache.GetDictionary<T>(key) as RedisHash<string, T>;
+        return _cacheProvider.Cache.GetDictionary<T>(key) as RedisHash<string, T>;
     }
 
     /// <summary>

+ 2 - 2
Admin.NET/Admin.NET.Core/Service/DataBase/SysDatabaseService.cs

@@ -316,7 +316,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
     /// <param name="input"></param>
     [ApiDescriptionSettings(Name = "CreateSeedData"), HttpPost]
     [DisplayName("创建种子数据")]
-    public async void CreateSeedData(CreateSeedDataInput input)
+    public async Task CreateSeedData(CreateSeedDataInput input)
     {
         var config = App.GetOptions<DbConnectionOptions>().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == input.ConfigId);
         input.Position = string.IsNullOrWhiteSpace(input.Position) ? "Admin.NET.Core" : input.Position;
@@ -333,7 +333,7 @@ public class SysDatabaseService : IDynamicApiController, ITransient
             entityType = item.Type;
             break;
         }
-        if (entityType == null) return;
+        if (entityType == null) throw Oops.Oh(ErrorCodeEnum.db1003);
 
         input.EntityName = entityType.Name;
         input.SeedDataName = entityType.Name + "SeedData";

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/Dict/SysDictTypeService.cs

@@ -168,7 +168,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
         var ds = await _sysDictTypeRep.AsQueryable()
             .InnerJoin<SysDictData>((u, a) => u.Id == a.DictTypeId)
             .Where((u, a) => u.IsDelete == false && a.IsDelete == false && a.Status == StatusEnum.Enable)
-            .Select((u, a) => new { TypeCode = u.Code, a.Code, a.Name, a.Value, a.Remark, a.OrderNo, a.TagType })
+            .Select((u, a) => new { TypeCode = u.Code, a.Code, a.Name, a.Value, a.Remark, a.OrderNo, a.TagType, a.ExtData })
             .ToListAsync();
         return ds.OrderBy(u => u.OrderNo).GroupBy(u => u.TypeCode).ToDictionary(u => u.Key, u => u);
     }

+ 38 - 44
Admin.NET/Admin.NET.Core/Service/File/SysFileService.cs

@@ -5,7 +5,6 @@
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
 using Aliyun.OSS.Util;
-using Furion.VirtualFileServer;
 using OnceMi.AspNetCore.OSS;
 
 namespace Admin.NET.Core.Service;
@@ -65,41 +64,27 @@ public class SysFileService : IDynamicApiController, ITransient
     }
 
     /// <summary>
-    /// 上传文件Base64
+    /// 上传文件Base64 🔖
     /// </summary>
-    /// <param name="strBase64"></param>
-    /// <param name="fileName"></param>
-    /// <param name="contentType"></param>
-    /// <param name="path"></param>
-    /// <param name="fileType"></param>
+    /// <param name="input"></param>
     /// <returns></returns>
-    private async Task<SysFile> UploadFileFromBase64(string strBase64, string fileName, string contentType, string? path, string? fileType)
+    [DisplayName("上传文件Base64")]
+    public async Task<SysFile> UploadFileFromBase64(UploadFileFromBase64Input input)
     {
-        byte[] fileData = Convert.FromBase64String(strBase64);
+        byte[] fileData = Convert.FromBase64String(input.FileDataBase64);
         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)
+        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 = contentType
+            ContentType = input.ContentType
         };
-        return await UploadFile(new FileUploadInput { File = formFile, Path = path, FileType = fileType });
-    }
-
-    /// <summary>
-    /// 上传文件Base64 🔖
-    /// </summary>
-    /// <param name="input"></param>
-    /// <returns></returns>
-    [DisplayName("上传文件Base64")]
-    public async Task<SysFile> UploadFileFromBase64(UploadFileFromBase64Input input)
-    {
-        return await UploadFileFromBase64(input.FileDataBase64, input.FileName, input.ContentType, input.Path, input.FileType);
+        return await UploadFile(new FileUploadInput { File = formFile, Path = input.Path, FileType = input.FileType });
     }
 
     /// <summary>
@@ -126,7 +111,7 @@ public class SysFileService : IDynamicApiController, ITransient
     [DisplayName("根据文件Id或Url下载")]
     public async Task<IActionResult> DownloadFile(FileInput input)
     {
-        var file = input.Id > 0 ? await GetFile(input) : await _sysFileRep.GetFirstAsync(u => u.Url == input.Url);
+        var file = input.Id > 0 ? await GetFile(input) : await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == input.Url);
         var fileName = HttpUtility.UrlEncode(file.FileName, Encoding.GetEncoding("UTF-8"));
 
         if (_OSSProviderOptions.IsEnable)
@@ -212,7 +197,7 @@ public class SysFileService : IDynamicApiController, ITransient
         }
         else if (App.Configuration["SSHProvider:IsEnable"].ToBoolean())
         {
-            var sysFile = await _sysFileRep.GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
+            var sysFile = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
             using (SSHHelper helper = new SSHHelper(App.Configuration["SSHProvider:Host"],
                App.Configuration["SSHProvider:Port"].ToInt(), App.Configuration["SSHProvider:Username"], App.Configuration["SSHProvider:Password"]))
             {
@@ -221,14 +206,17 @@ public class SysFileService : IDynamicApiController, ITransient
         }
         else
         {
-            var sysFile = await _sysFileRep.GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
+            var sysFile = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Url == url) ?? throw Oops.Oh($"文件不存在");
             var filePath = Path.Combine(App.WebHostEnvironment.WebRootPath, sysFile.FilePath);
             if (!Directory.Exists(filePath))
                 Directory.CreateDirectory(filePath);
 
             var realFile = Path.Combine(filePath, $"{sysFile.Id}{sysFile.Suffix}");
             if (!File.Exists(realFile))
-                throw Oops.Oh($"文件[{realFile}]不在存");
+            {
+                Log.Error($"DownloadFileBase64:文件[{realFile}]不存在");
+                throw Oops.Oh($"文件[{sysFile.FilePath}]不存在");
+            }
             byte[] fileBytes = File.ReadAllBytes(realFile);
             return Convert.ToBase64String(fileBytes);
         }
@@ -292,7 +280,7 @@ public class SysFileService : IDynamicApiController, ITransient
     /// <returns></returns>
     private async Task<SysFile> GetFile([FromQuery] FileInput input)
     {
-        var file = await _sysFileRep.GetFirstAsync(u => u.Id == input.Id);
+        var file = await _sysFileRep.CopyNew().GetFirstAsync(u => u.Id == input.Id);
         return file ?? throw Oops.Oh(ErrorCodeEnum.D8000);
     }
 
@@ -336,9 +324,11 @@ public class SysFileService : IDynamicApiController, ITransient
         // 获取文件后缀
         var suffix = Path.GetExtension(file.FileName).ToLower(); // 后缀
         if (string.IsNullOrWhiteSpace(suffix))
+            suffix = string.Concat(".", file.ContentType.AsSpan(file.ContentType.LastIndexOf('/') + 1));
+        if (!string.IsNullOrWhiteSpace(suffix))
         {
-            var contentTypeProvider = FS.GetFileExtensionContentTypeProvider();
-            suffix = contentTypeProvider.Mappings.FirstOrDefault(u => u.Value == file.ContentType).Key;
+            //var contentTypeProvider = FS.GetFileExtensionContentTypeProvider();
+            //suffix = contentTypeProvider.Mappings.FirstOrDefault(u => u.Value == file.ContentType).Key;
             // 修改 image/jpeg 类型返回的 .jpeg、jpe 后缀
             if (suffix == ".jpeg" || suffix == ".jpe")
                 suffix = ".jpg";
@@ -383,6 +373,10 @@ public class SysFileService : IDynamicApiController, ITransient
                     newFile.Url = $"{(_OSSProviderOptions.IsEnableHttps ? "https" : "http")}://{newFile.BucketName}.{_OSSProviderOptions.Endpoint}/{filePath}";
                     break;
 
+                case OSSProvider.QCloud:
+                    newFile.Url = $"{(_OSSProviderOptions.IsEnableHttps ? "https" : "http")}://{newFile.BucketName}-{_OSSProviderOptions.Endpoint}.cos.{_OSSProviderOptions.Region}.myqcloud.com/{filePath}";
+                    break;
+
                 case OSSProvider.Minio:
                     // 获取Minio文件的下载或者预览地址
                     // newFile.Url = await GetMinioPreviewFileUrl(newFile.BucketName, filePath);// 这种方法生成的Url是有7天有效期的,不能这样使用
@@ -492,11 +486,11 @@ public class SysFileService : IDynamicApiController, ITransient
         if (ids == null || ids.Count == 0)
             return 0;
         return await _sysFileRep.AsUpdateable()
-              .SetColumns(m => m.RelationName == relationName)
-              .SetColumns(m => m.RelationId == relationId)
-              .SetColumns(m => m.BelongId == belongId)
-             .Where(m => ids.Contains(m.Id))
-             .ExecuteCommandAsync();
+            .SetColumns(m => m.RelationName == relationName)
+            .SetColumns(m => m.RelationId == relationId)
+            .SetColumns(m => m.BelongId == belongId)
+            .Where(m => ids.Contains(m.Id))
+            .ExecuteCommandAsync();
     }
 
     /// <summary>
@@ -508,11 +502,11 @@ public class SysFileService : IDynamicApiController, ITransient
     public async Task<List<FileOutput>> GetRelationFiles([FromQuery] RelationQueryInput input)
     {
         return await _sysFileRep.AsQueryable()
-           .Where(m => !m.IsDelete)
-           .WhereIF(input.RelationId.HasValue && input.RelationId > 0, m => m.RelationId == input.RelationId)
-           .WhereIF(input.BelongId.HasValue && input.BelongId > 0, m => m.BelongId == input.BelongId.Value)
-           .WhereIF(!string.IsNullOrWhiteSpace(input.RelationName), m => m.RelationName == input.RelationName)
-           .WhereIF(!string.IsNullOrWhiteSpace(input.FileTypes), m => input.GetFileTypeBS().Contains(m.FileType))
+            .Where(m => !m.IsDelete)
+            .WhereIF(input.RelationId.HasValue && input.RelationId > 0, m => m.RelationId == input.RelationId)
+            .WhereIF(input.BelongId.HasValue && input.BelongId > 0, m => m.BelongId == input.BelongId.Value)
+            .WhereIF(!string.IsNullOrWhiteSpace(input.RelationName), m => m.RelationName == input.RelationName)
+            .WhereIF(!string.IsNullOrWhiteSpace(input.FileTypes), m => input.GetFileTypeBS().Contains(m.FileType))
             .Select(m => new FileOutput
             {
                 Id = m.Id,

+ 106 - 106
Admin.NET/Admin.NET.Core/Service/Job/JobClusterServer.cs

@@ -1,107 +1,107 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
-//
-// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
-//
-// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
-
-namespace Admin.NET.Core.Service;
-
-/// <summary>
-/// 作业集群控制
-/// </summary>
-public class JobClusterServer : IJobClusterServer
-{
-    private readonly Random rd = new(DateTime.Now.Millisecond);
-
-    public JobClusterServer()
-    {
-    }
-
-    /// <summary>
-    /// 当前作业调度器启动通知
-    /// </summary>
-    /// <param name="context">作业集群服务上下文</param>
-    public async void Start(JobClusterContext context)
-    {
-        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
-        // 在作业集群表中,如果 clusterId 不存在,则新增一条(否则更新一条),并设置 status 为 ClusterStatus.Waiting
-        if (await _sysJobClusterRep.IsAnyAsync(u => u.ClusterId == context.ClusterId))
-        {
-            await _sysJobClusterRep.AsUpdateable().SetColumns(u => u.Status == ClusterStatus.Waiting).Where(u => u.ClusterId == context.ClusterId).ExecuteCommandAsync();
-        }
-        else
-        {
-            await _sysJobClusterRep.AsInsertable(new SysJobCluster { ClusterId = context.ClusterId, Status = ClusterStatus.Waiting }).ExecuteCommandAsync();
-        }
-    }
-
-    /// <summary>
-    /// 等待被唤醒
-    /// </summary>
-    /// <param name="context">作业集群服务上下文</param>
-    /// <returns><see cref="Task"/></returns>
-    public async Task WaitingForAsync(JobClusterContext context)
-    {
-        var clusterId = context.ClusterId;
-
-        while (true)
-        {
-            // 控制集群心跳频率(放在头部为了防止 IsAnyAsync continue 没sleep占用大量IO和CPU)
-            await Task.Delay(3000 + rd.Next(500, 1000)); // 错开集群同时启动
-
-            try
-            {
-                ICache _cache = App.GetRequiredService<ICache>();
-                // 使用分布式锁
-                using (_cache.AcquireLock("lock:JobClusterServer:WaitingForAsync", 1000))
-                {
-                    var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
-                    // 在这里查询数据库,根据以下两种情况处理
-                    // 1) 如果作业集群表已有 status 为 ClusterStatus.Working 则继续循环
-                    // 2) 如果作业集群表中还没有其他服务或只有自己,则插入一条集群服务或调用 await WorkNowAsync(clusterId); 之后 return;
-                    // 3) 如果作业集群表中没有 status 为 ClusterStatus.Working 的,调用 await WorkNowAsync(clusterId); 之后 return;
-                    if (await _sysJobClusterRep.IsAnyAsync(u => u.Status == ClusterStatus.Working))
-                        continue;
-
-                    await WorkNowAsync(clusterId);
-                    return;
-                }
-            }
-            catch { }
-        }
-    }
-
-    /// <summary>
-    /// 当前作业调度器停止通知
-    /// </summary>
-    /// <param name="context">作业集群服务上下文</param>
-    public async void Stop(JobClusterContext context)
-    {
-        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
-        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Crashed
-        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Crashed }, u => u.ClusterId == context.ClusterId);
-    }
-
-    /// <summary>
-    /// 当前作业调度器宕机
-    /// </summary>
-    /// <param name="context">作业集群服务上下文</param>
-    public async void Crash(JobClusterContext context)
-    {
-        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
-        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Crashed
-        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Crashed }, u => u.ClusterId == context.ClusterId);
-    }
-
-    /// <summary>
-    /// 指示集群可以工作
-    /// </summary>
-    /// <param name="clusterId">集群 Id</param>
-    /// <returns></returns>
-    private static async Task WorkNowAsync(string clusterId)
-    {
-        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
-        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Working
-        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Working }, u => u.ClusterId == clusterId);
-    }
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core.Service;
+
+/// <summary>
+/// 作业集群控制
+/// </summary>
+public class JobClusterServer : IJobClusterServer
+{
+    private readonly Random rd = new(DateTime.Now.Millisecond);
+
+    public JobClusterServer()
+    {
+    }
+
+    /// <summary>
+    /// 当前作业调度器启动通知
+    /// </summary>
+    /// <param name="context">作业集群服务上下文</param>
+    public async void Start(JobClusterContext context)
+    {
+        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
+        // 在作业集群表中,如果 clusterId 不存在,则新增一条(否则更新一条),并设置 status 为 ClusterStatus.Waiting
+        if (await _sysJobClusterRep.IsAnyAsync(u => u.ClusterId == context.ClusterId))
+        {
+            await _sysJobClusterRep.AsUpdateable().SetColumns(u => u.Status == ClusterStatus.Waiting).Where(u => u.ClusterId == context.ClusterId).ExecuteCommandAsync();
+        }
+        else
+        {
+            await _sysJobClusterRep.AsInsertable(new SysJobCluster { ClusterId = context.ClusterId, Status = ClusterStatus.Waiting }).ExecuteCommandAsync();
+        }
+    }
+
+    /// <summary>
+    /// 等待被唤醒
+    /// </summary>
+    /// <param name="context">作业集群服务上下文</param>
+    /// <returns><see cref="Task"/></returns>
+    public async Task WaitingForAsync(JobClusterContext context)
+    {
+        var clusterId = context.ClusterId;
+
+        while (true)
+        {
+            // 控制集群心跳频率(放在头部为了防止 IsAnyAsync continue 没sleep占用大量IO和CPU)
+            await Task.Delay(3000 + rd.Next(500, 1000)); // 错开集群同时启动
+
+            try
+            {
+                ICache _cache = App.GetRequiredService<ICacheProvider>().Cache;
+                // 使用分布式锁
+                using (_cache.AcquireLock("lock:JobClusterServer:WaitingForAsync", 1000))
+                {
+                    var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
+                    // 在这里查询数据库,根据以下两种情况处理
+                    // 1) 如果作业集群表已有 status 为 ClusterStatus.Working 则继续循环
+                    // 2) 如果作业集群表中还没有其他服务或只有自己,则插入一条集群服务或调用 await WorkNowAsync(clusterId); 之后 return;
+                    // 3) 如果作业集群表中没有 status 为 ClusterStatus.Working 的,调用 await WorkNowAsync(clusterId); 之后 return;
+                    if (await _sysJobClusterRep.IsAnyAsync(u => u.Status == ClusterStatus.Working))
+                        continue;
+
+                    await WorkNowAsync(clusterId);
+                    return;
+                }
+            }
+            catch { }
+        }
+    }
+
+    /// <summary>
+    /// 当前作业调度器停止通知
+    /// </summary>
+    /// <param name="context">作业集群服务上下文</param>
+    public async void Stop(JobClusterContext context)
+    {
+        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
+        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Crashed
+        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Crashed }, u => u.ClusterId == context.ClusterId);
+    }
+
+    /// <summary>
+    /// 当前作业调度器宕机
+    /// </summary>
+    /// <param name="context">作业集群服务上下文</param>
+    public async void Crash(JobClusterContext context)
+    {
+        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
+        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Crashed
+        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Crashed }, u => u.ClusterId == context.ClusterId);
+    }
+
+    /// <summary>
+    /// 指示集群可以工作
+    /// </summary>
+    /// <param name="clusterId">集群 Id</param>
+    /// <returns></returns>
+    private static async Task WorkNowAsync(string clusterId)
+    {
+        var _sysJobClusterRep = App.GetRequiredService<SqlSugarRepository<SysJobCluster>>();
+        // 在作业集群表中,更新 clusterId 的 status 为 ClusterStatus.Working
+        await _sysJobClusterRep.UpdateAsync(u => new SysJobCluster { Status = ClusterStatus.Working }, u => u.ClusterId == clusterId);
+    }
 }

+ 0 - 1
Admin.NET/Admin.NET.Core/Service/Message/SysSmsService.cs

@@ -8,7 +8,6 @@ using AlibabaCloud.SDK.Dysmsapi20170525.Models;
 using TencentCloud.Common;
 using TencentCloud.Common.Profile;
 using TencentCloud.Sms.V20190711;
-using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBBatchCreateContainerServiceVersionRequest.Types;
 
 namespace Admin.NET.Core.Service;
 

+ 4 - 0
Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs

@@ -169,6 +169,10 @@ public class SysUserService : IDynamicApiController, ITransient
             throw Oops.Oh(ErrorCodeEnum.D1014);
         if (user.Id == _userManager.UserId)
             throw Oops.Oh(ErrorCodeEnum.D1001);
+        // 若账号为租户默认账号则禁止删除
+        var isTenantUser = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().IsAnyAsync(u => u.UserId == input.Id);
+        if (isTenantUser)
+            throw Oops.Oh(ErrorCodeEnum.D1029);
 
         // 强制下线
         await _sysOnlineUserService.ForceOffline(user.Id);

+ 47 - 1
Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayInput.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -32,6 +32,16 @@ public class WechatPayTransactionInput
     /// 优惠标记
     /// </summary>
     public string GoodsTag { get; set; }
+
+    /// <summary>
+    /// 业务标签,用来区分做什么业务
+    /// </summary>
+    public string Tags { get; set; }
+
+    /// <summary>
+    /// 对应业务的主键
+    /// </summary>
+    public long BusinessId { get; set; }
 }
 
 public class WechatPayParaInput
@@ -40,4 +50,40 @@ public class WechatPayParaInput
     /// 订单Id
     /// </summary>
     public string PrepayId { get; set; }
+}
+
+public class WechatPayRefundDomesticInput
+{
+    /// <summary>
+    /// 商户端生成的业务流水号
+    /// </summary>
+    [Required]
+    public string TradeId { get; set; }
+
+    /// <summary>
+    /// 退款原因
+    /// </summary>
+    public string Reason { get; set; }
+
+    /// <summary>
+    /// 退款金额
+    /// </summary>
+    [Required]
+    public int Refund { get; set; }
+
+    /// <summary>
+    /// 原订单金额
+    /// </summary>
+    [Required]
+    public int Total { get; set; }
+}
+
+public class WechatPayPageInput : BasePageInput
+{
+    public string SearchKey { get; set; }
+
+    /// <summary>
+    /// 添加时间范围
+    /// </summary>
+    public List<DateTime?> CreateTimeRange { get; set; }
 }

+ 25 - 1
Admin.NET/Admin.NET.Core/Service/Wechat/Dto/WechatPayOutput.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -27,4 +27,28 @@ public class WechatPayOutput
     /// 优惠标记
     /// </summary>
     public string GoodsTag { get; set; }
+}
+
+public class WechatPayTransactionOutput
+{
+    public string PrepayId { get; set; }
+
+    public string OutTradeNumber { get; set; }
+
+    public WechatPayParaOutput SingInfo { get; set; }
+}
+
+public class WechatPayParaOutput
+{
+    public string AppId { get; set; }
+
+    public string TimeStamp { get; set; }
+
+    public string NonceStr { get; set; }
+
+    public string Package { get; set; }
+
+    public string SignType { get; set; }
+
+    public string PaySign { get; set; }
 }

+ 315 - 46
Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatPayService.cs

@@ -1,9 +1,12 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+using Furion.Logging.Extensions;
+using Newtonsoft.Json;
+
 namespace Admin.NET.Core.Service;
 
 /// <summary>
@@ -12,7 +15,8 @@ namespace Admin.NET.Core.Service;
 [ApiDescriptionSettings(Order = 210)]
 public class SysWechatPayService : IDynamicApiController, ITransient
 {
-    private readonly SqlSugarRepository<SysWechatPay> _sysWechatPayUserRep;
+    private readonly SqlSugarRepository<SysWechatPay> _sysWechatPayRep;
+    private readonly SqlSugarRepository<SysWechatRefund> _sysWechatRefundRep;
 
     private readonly WechatPayOptions _wechatPayOptions;
     private readonly PayCallBackOptions _payCallBackOptions;
@@ -20,10 +24,12 @@ public class SysWechatPayService : IDynamicApiController, ITransient
     private readonly WechatTenpayClient _wechatTenpayClient;
 
     public SysWechatPayService(SqlSugarRepository<SysWechatPay> sysWechatPayUserRep,
+        SqlSugarRepository<SysWechatRefund> sysWechatRefundRep,
         IOptions<WechatPayOptions> wechatPayOptions,
         IOptions<PayCallBackOptions> payCallBackOptions)
     {
-        _sysWechatPayUserRep = sysWechatPayUserRep;
+        _sysWechatPayRep = sysWechatPayUserRep;
+        _sysWechatRefundRep = sysWechatRefundRep;
         _wechatPayOptions = wechatPayOptions.Value;
         _payCallBackOptions = payCallBackOptions.Value;
 
@@ -49,22 +55,61 @@ public class SysWechatPayService : IDynamicApiController, ITransient
         return new WechatTenpayClient(tenpayClientOptions);
     }
 
+    /// <summary>
+    /// 分页查询支付列表 🔖
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [HttpPost]
+    [ApiDescriptionSettings(Name = "Page")]
+    public async Task<SqlSugarPagedList<SysWechatPay>> Page(WechatPayPageInput input)
+    {
+        var query = _sysWechatPayRep.AsQueryable()
+            .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.OutTradeNumber == input.SearchKey || u.TransactionId == input.SearchKey)
+            .WhereIF(input.CreateTimeRange != null && input.CreateTimeRange.Count > 0 && input.CreateTimeRange[0].HasValue, x => x.CreateTime >= input.CreateTimeRange[0])
+            .WhereIF(input.CreateTimeRange != null && input.CreateTimeRange.Count > 1 && input.CreateTimeRange[1].HasValue, x => x.CreateTime < ((DateTime)input.CreateTimeRange[1]).AddDays(1));
+        return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
+    }
+
+    /// <summary>
+    /// 查询退款信息列表
+    /// </summary>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [HttpPost]
+    [DisplayName("根据支付id获取退款信息列表")]
+    public async Task<List<SysWechatRefund>> ListRefund([FromBody] string id)
+    {
+        var query = _sysWechatRefundRep.AsQueryable()
+            .Where(u => u.TransactionId == id);
+        return await query.ToListAsync();
+    }
+
     /// <summary>
     /// 生成JSAPI调起支付所需参数 🔖
     /// </summary>
     /// <param name="input"></param>
     /// <returns></returns>
     [DisplayName("生成JSAPI调起支付所需参数")]
-    public dynamic GenerateParametersForJsapiPay(WechatPayParaInput input)
+    public WechatPayParaOutput GenerateParametersForJsapiPay(WechatPayParaInput input)
     {
-        return _wechatTenpayClient.GenerateParametersForJsapiPayRequest(_wechatPayOptions.AppId, input.PrepayId);
+        var data = _wechatTenpayClient.GenerateParametersForJsapiPayRequest(_wechatPayOptions.AppId, input.PrepayId);
+        return new WechatPayParaOutput()
+        {
+            AppId = data["appId"],
+            TimeStamp = data["timeStamp"],
+            NonceStr = data["nonceStr"],
+            Package = data["package"],
+            SignType = data["signType"],
+            PaySign = data["paySign"]
+        };
     }
 
     /// <summary>
-    /// 微信支付统一下单获取Id(商户直连) 🔖
+    /// 微信支付下单(商户直连) 🔖
     /// </summary>
-    [DisplayName("微信支付统一下单获取Id(商户直连)")]
-    public async Task<dynamic> CreatePayTransaction([FromBody] WechatPayTransactionInput input)
+    [DisplayName("微信支付下单(商户直连)")]
+    public async Task<WechatPayTransactionOutput> CreatePayTransaction([FromBody] WechatPayTransactionInput input)
     {
         var request = new CreatePayTransactionJsapiRequest()
         {
@@ -82,6 +127,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
         if (!response.IsSuccessful())
             throw Oops.Oh(response.ErrorMessage);
 
+        var singInfo = this.GenerateParametersForJsapiPay(new WechatPayParaInput() { PrepayId = response.PrepayId });
         // 保存订单信息
         var wechatPay = new SysWechatPay()
         {
@@ -93,21 +139,73 @@ public class SysWechatPayService : IDynamicApiController, ITransient
             GoodsTag = input.GoodsTag,
             Total = input.Total,
             OpenId = input.OpenId,
-            TransactionId = ""
+            TransactionId = "",
+            Tags = input.Tags,
+            BusinessId = input.BusinessId,
         };
-        await _sysWechatPayUserRep.InsertAsync(wechatPay);
+        await _sysWechatPayRep.InsertAsync(wechatPay);
+
+        return new WechatPayTransactionOutput()
+        {
+            PrepayId = response.PrepayId,
+            OutTradeNumber = request.OutTradeNumber,
+            SingInfo = singInfo
+        };
+    }
 
+    /// <summary>
+    /// 微信支付下单(商户直连)Native
+    /// </summary>
+    [DisplayName("微信支付下单(商户直连)Native")]
+    public async Task<dynamic> CreatePayTransactionNative([FromBody] WechatPayTransactionInput input)
+    {
+        var request = new CreatePayTransactionNativeRequest()
+        {
+            OutTradeNumber = DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000), // 订单号
+            AppId = _wechatPayOptions.AppId,
+            Description = input.Description,
+            Attachment = input.Attachment,
+            GoodsTag = input.GoodsTag,
+            ExpireTime = DateTimeOffset.Now.AddMinutes(10),
+            NotifyUrl = _payCallBackOptions.WechatPayUrl,
+            Amount = new CreatePayTransactionNativeRequest.Types.Amount() { Total = input.Total },
+            //Payer = new CreatePayTransactionNativeRequest.Types.Payer() { OpenId = input.OpenId }
+            Scene = new CreatePayTransactionNativeRequest.Types.Scene() { ClientIp = "127.0.0.1" }
+        };
+        var response = await _wechatTenpayClient.ExecuteCreatePayTransactionNativeAsync(request);
+        if (!response.IsSuccessful())
+        {
+            JsonConvert.SerializeObject(response).LogInformation();
+            throw Oops.Oh(response.ErrorMessage);
+        }
+        // 保存订单信息
+        var wechatPay = new SysWechatPay()
+        {
+            AppId = _wechatPayOptions.AppId,
+            MerchantId = _wechatPayOptions.MerchantId,
+            OutTradeNumber = request.OutTradeNumber,
+            Description = input.Description,
+            Attachment = input.Attachment,
+            GoodsTag = input.GoodsTag,
+            Total = input.Total,
+            //OpenId = input.OpenId,
+            TransactionId = "",
+            QrcodeContent = response.QrcodeUrl,
+            Tags = input.Tags,
+            BusinessId = input.BusinessId,
+        };
+        await _sysWechatPayRep.InsertAsync(wechatPay);
         return new
         {
-            response.PrepayId,
-            request.OutTradeNumber
+            request.OutTradeNumber,
+            response.QrcodeUrl
         };
     }
 
     /// <summary>
-    /// 微信支付统一下单获取Id(服务商模式) 🔖
+    /// 微信支付下单(服务商模式) 🔖
     /// </summary>
-    [DisplayName("微信支付统一下单获取Id(服务商模式)")]
+    [DisplayName("微信支付下单(服务商模式)")]
     public async Task<dynamic> CreatePayPartnerTransaction([FromBody] WechatPayTransactionInput input)
     {
         var request = new CreatePayPartnerTransactionJsapiRequest()
@@ -128,7 +226,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
         var response = await _wechatTenpayClient.ExecuteCreatePayPartnerTransactionJsapiAsync(request);
         if (!response.IsSuccessful())
             throw Oops.Oh(response.ErrorMessage);
-
+        var singInfo = this.GenerateParametersForJsapiPay(new WechatPayParaInput() { PrepayId = response.PrepayId });
         // 保存订单信息
         var wechatPay = new SysWechatPay()
         {
@@ -144,28 +242,167 @@ public class SysWechatPayService : IDynamicApiController, ITransient
             OpenId = input.OpenId,
             TransactionId = ""
         };
-        await _sysWechatPayUserRep.InsertAsync(wechatPay);
+        await _sysWechatPayRep.InsertAsync(wechatPay);
 
         return new
         {
             response.PrepayId,
-            request.OutTradeNumber
+            request.OutTradeNumber,
+            singInfo
         };
     }
 
     /// <summary>
-    /// 获取支付订单详情 🔖
+    /// 获取支付订单详情(本地库) 🔖
     /// </summary>
     /// <param name="tradeId"></param>
     /// <returns></returns>
-    [DisplayName("获取支付订单详情")]
+    [DisplayName("获取支付订单详情(本地库)")]
     public async Task<SysWechatPay> GetPayInfo(string tradeId)
     {
-        return await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == tradeId);
+        return await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == tradeId);
+    }
+
+    /// <summary>
+    /// 获取支付订单详情(微信接口) 🔖
+    /// </summary>
+    /// <param name="tradeId"></param>
+    /// <returns></returns>
+    [DisplayName("获取支付订单详情(微信接口)")]
+    public async Task<SysWechatPay> GetPayInfoFromWechat(string tradeId)
+    {
+        var request = new GetPayTransactionByOutTradeNumberRequest();
+        request.OutTradeNumber = tradeId;
+        var response = await _wechatTenpayClient.ExecuteGetPayTransactionByOutTradeNumberAsync(request);
+        // 修改订单支付状态
+        var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == response.OutTradeNumber
+            && u.MerchantId == response.MerchantId);
+        // 如果状态不一致就更新数据库中的记录
+        if (wechatPay != null && wechatPay.TradeState != response.TradeState)
+        {
+            wechatPay.OpenId = response.Payer.OpenId;
+            wechatPay.TransactionId = response.TransactionId; // 支付订单号
+            wechatPay.TradeType = response.TradeType; // 交易类型
+            wechatPay.TradeState = response.TradeState; // 交易状态
+            wechatPay.TradeStateDescription = response.TradeStateDescription; // 交易状态描述
+            wechatPay.BankType = response.BankType; // 付款银行类型
+            wechatPay.Total = response.Amount.Total; // 订单总金额
+            wechatPay.PayerTotal = response.Amount.PayerTotal; // 用户支付金额
+            wechatPay.SuccessTime = response.SuccessTime.Value.DateTime; // 支付完成时间
+            await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
+        }
+        wechatPay = new SysWechatPay()
+        {
+            AppId = _wechatPayOptions.AppId,
+            MerchantId = _wechatPayOptions.MerchantId,
+            SubAppId = _wechatPayOptions.AppId,
+            SubMerchantId = _wechatPayOptions.MerchantId,
+            OutTradeNumber = request.OutTradeNumber,
+            Attachment = response.Attachment,
+            Total = response.Amount.Total, // 订单总金额
+            TransactionId = response.TransactionId,
+            TradeType = response.TradeType, // 交易类型
+            TradeState = response.TradeState, // 交易状态
+            TradeStateDescription = response.TradeStateDescription, // 交易状态描述
+            BankType = response.BankType, // 付款银行类型
+            PayerTotal = response.Amount.PayerTotal, // 用户支付金额
+            SuccessTime = response.SuccessTime.Value.DateTime // 支付完成时间
+        };
+        return wechatPay;
     }
 
     /// <summary>
-    /// 微信支付成功回调(商户直连) 🔖
+    /// 退款申请
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [DisplayName("退款申请")]
+    [HttpPost]
+    public async Task<dynamic> CreateRefundDomestic([FromBody] WechatPayRefundDomesticInput input)
+    {
+        // refund/domestic/refunds
+        var request = new CreateRefundDomesticRefundRequest()
+        {
+            Amount = new CreateRefundDomesticRefundRequest.Types.Amount()
+            {
+                Refund = input.Refund,
+                Total = input.Total,
+                Currency = "CNY"
+            },
+
+            OutTradeNumber = input.TradeId,
+            OutRefundNumber = "R" + DateTimeOffset.Now.ToString("yyyyMMddHHmmssfff") + (new Random()).Next(100, 1000), // 订单号
+            NotifyUrl = _payCallBackOptions.WechatPayUrl,
+            Reason = input.Reason,
+        };
+        var response = await _wechatTenpayClient.ExecuteCreateRefundDomesticRefundAsync(request);
+        if (string.IsNullOrEmpty(response.ErrorCode))
+        {
+            // 成功了,这里应该保存退款订单信息
+            var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == response.OutTradeNumber);
+            // 保存订单信息
+            if (wechatPay != null)
+            {
+                var wechatRefund = new SysWechatRefund()
+                {
+                    WechatPayId = wechatPay.Id,
+                    TransactionId = response.TransactionId,
+                    Refund = input.Refund,
+                    Reason = input.Reason,
+                    OutRefundNumber = request.OutRefundNumber,
+                    Channel = response.Channel,
+                    UserReceivedAccount = response.UserReceivedAccount,
+                };
+                await _sysWechatRefundRep.InsertAsync(wechatRefund);
+            }
+        }
+        else
+        {
+            throw Oops.Bah($"[{response.ErrorCode}]{response.ErrorMessage}");
+        }
+        return response;
+    }
+
+    /// <summary>
+    /// 获取退款订单详情(微信接口)
+    /// </summary>
+    /// <param name="refundId"></param>
+    /// <returns></returns>
+    [DisplayName("获取退款订单详情(微信接口)")]
+    public async Task<SysWechatRefund> GetRefundInfoFromWechat(string refundId)
+    {
+        var request = new GetRefundDomesticRefundByOutRefundNumberRequest();
+        request.OutRefundNumber = refundId;
+        var response = await _wechatTenpayClient.ExecuteGetRefundDomesticRefundByOutRefundNumberAsync(request);
+        // 修改订单支付状态
+        var wechatRefund = await _sysWechatRefundRep.GetFirstAsync(u => u.OutRefundNumber == refundId);
+        // 如果状态不一致就更新数据库中的记录
+        if (wechatRefund != null && wechatRefund.TradeState != response.Status)
+        {
+            wechatRefund.TransactionId = response.TransactionId; // 支付订单号
+            wechatRefund.TradeState = response.Status; // 交易状态
+            wechatRefund.SuccessTime = response.SuccessTime.Value.DateTime; // 支付完成时间
+            await _sysWechatRefundRep.AsUpdateable(wechatRefund).IgnoreColumns(true).ExecuteCommandAsync();
+            // 有退款,刷新一下订单状态
+            var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.Id == wechatRefund.WechatPayId);
+            if (wechatPay != null)
+                await GetPayInfoFromWechat(wechatPay.OutTradeNumber);
+        }
+        wechatRefund = new SysWechatRefund()
+        {
+            TransactionId = response.TransactionId,
+            Refund = response.Amount.Refund,
+            OutRefundNumber = request.OutRefundNumber,
+            Channel = response.Channel,
+            UserReceivedAccount = response.UserReceivedAccount,
+            TradeState = response.Status, // 交易状态
+            SuccessTime = response.SuccessTime.Value.DateTime, // 支付完成时间
+        };
+        return wechatRefund;
+    }
+
+    /// <summary>
+    /// 微信支付成功回调(商户直连)
     /// </summary>
     /// <returns></returns>
     [AllowAnonymous]
@@ -180,32 +417,64 @@ public class SysWechatPayService : IDynamicApiController, ITransient
         var callbackModel = _wechatTenpayClient.DeserializeEvent(callbackJson);
         if ("TRANSACTION.SUCCESS".Equals(callbackModel.EventType))
         {
-            var callbackResource = _wechatTenpayClient.DecryptEventResource<TransactionResource>(callbackModel);
+            try
+            {
+                var callbackPayResource = _wechatTenpayClient.DecryptEventResource<TransactionResource>(callbackModel);
 
-            // 修改订单支付状态
-            var wechatPay = await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
-                && u.MerchantId == callbackResource.MerchantId);
-            if (wechatPay == null) return null;
-            //wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识
-            //wechatPay.MerchantId = callbackResource.MerchantId; // 微信商户号
-            //wechatPay.OutTradeNumber = callbackResource.OutTradeNumber; // 商户订单号
-            wechatPay.TransactionId = callbackResource.TransactionId; // 支付订单号
-            wechatPay.TradeType = callbackResource.TradeType; // 交易类型
-            wechatPay.TradeState = callbackResource.TradeState; // 交易状态
-            wechatPay.TradeStateDescription = callbackResource.TradeStateDescription; // 交易状态描述
-            wechatPay.BankType = callbackResource.BankType; // 付款银行类型
-            wechatPay.Total = callbackResource.Amount.Total; // 订单总金额
-            wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额
-            wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间
+                // 修改订单支付状态
+                var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackPayResource.OutTradeNumber
+                    && u.MerchantId == callbackPayResource.MerchantId);
+                if (wechatPay == null) return null;
+                wechatPay.OpenId = callbackPayResource.Payer.OpenId; // 支付者标识
+                //wechatPay.MerchantId = callbackResource.MerchantId; // 微信商户号
+                //wechatPay.OutTradeNumber = callbackResource.OutTradeNumber; // 商户订单号
+                wechatPay.TransactionId = callbackPayResource.TransactionId; // 支付订单号
+                wechatPay.TradeType = callbackPayResource.TradeType; // 交易类型
+                wechatPay.TradeState = callbackPayResource.TradeState; // 交易状态
+                wechatPay.TradeStateDescription = callbackPayResource.TradeStateDescription; // 交易状态描述
+                wechatPay.BankType = callbackPayResource.BankType; // 付款银行类型
+                wechatPay.Total = callbackPayResource.Amount.Total; // 订单总金额
+                wechatPay.PayerTotal = callbackPayResource.Amount.PayerTotal; // 用户支付金额
+                wechatPay.SuccessTime = callbackPayResource.SuccessTime.DateTime; // 支付完成时间
 
-            await _sysWechatPayUserRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
+                await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
 
-            return new WechatPayOutput()
+                return new WechatPayOutput()
+                {
+                    Total = wechatPay.Total,
+                    Attachment = wechatPay.Attachment,
+                    GoodsTag = wechatPay.GoodsTag
+                };
+            }
+            catch (Exception ex)
             {
-                Total = wechatPay.Total,
-                Attachment = wechatPay.Attachment,
-                GoodsTag = wechatPay.GoodsTag
-            };
+                "微信支付回调时出错:".LogError(ex);
+            }
+        }
+        else if ("REFUND.SUCCESS".Equals(callbackModel.EventType))
+        {
+            //参考:https://pay.weixin.qq.com/docs/merchant/apis/jsapi-payment/refund-result-notice.html
+            try
+            {
+                var callbackRefundResource = _wechatTenpayClient.DecryptEventResource<RefundResource>(callbackModel);
+                // 修改订单支付状态
+                var wechatRefund = await _sysWechatRefundRep.GetFirstAsync(u => u.OutRefundNumber == callbackRefundResource.OutRefundNumber);
+                if (wechatRefund == null) return null;
+                wechatRefund.TradeState = callbackRefundResource.RefundStatus; // 交易状态
+                wechatRefund.SuccessTime = callbackRefundResource.SuccessTime.Value.DateTime; // 支付完成时间
+
+                await _sysWechatRefundRep.AsUpdateable(wechatRefund).IgnoreColumns(true).ExecuteCommandAsync();
+                // 有退款,刷新一下订单状态
+                await GetPayInfoFromWechat(callbackRefundResource.OutTradeNumber);
+            }
+            catch (Exception ex)
+            {
+                "微信退款回调时出错:".LogError(ex);
+            }
+        }
+        else
+        {
+            callbackModel.EventType.LogInformation();
         }
 
         return null;
@@ -230,7 +499,7 @@ public class SysWechatPayService : IDynamicApiController, ITransient
             var callbackResource = _wechatTenpayClient.DecryptEventResource<PartnerTransactionResource>(callbackModel);
 
             // 修改订单支付状态
-            var wechatPay = await _sysWechatPayUserRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
+            var wechatPay = await _sysWechatPayRep.GetFirstAsync(u => u.OutTradeNumber == callbackResource.OutTradeNumber
                 && u.MerchantId == callbackResource.MerchantId);
             if (wechatPay == null) return;
             //wechatPay.OpenId = callbackResource.Payer.OpenId; // 支付者标识
@@ -243,9 +512,9 @@ public class SysWechatPayService : IDynamicApiController, ITransient
             wechatPay.BankType = callbackResource.BankType; // 付款银行类型
             wechatPay.Total = callbackResource.Amount.Total; // 订单总金额
             wechatPay.PayerTotal = callbackResource.Amount.PayerTotal; // 用户支付金额
-            wechatPay.SuccessTime = callbackResource.SuccessTime; // 支付完成时间
+            wechatPay.SuccessTime = callbackResource.SuccessTime.DateTime; // 支付完成时间
 
-            await _sysWechatPayUserRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
+            await _sysWechatPayRep.AsUpdateable(wechatPay).IgnoreColumns(true).ExecuteCommandAsync();
         }
     }
 }

+ 2 - 1
Admin.NET/Admin.NET.Core/Service/Wechat/SysWechatService.cs

@@ -199,7 +199,8 @@ public class SysWechatService : IDynamicApiController, ITransient
     /// <summary>
     /// 获取Access_token
     /// </summary>
-    private async Task<string> GetCgibinToken()
+    [NonAction]
+    public async Task<string> GetCgibinToken()
     {
         // 先从缓存中取 AccessToken
         var wx_accessToken = _sysCacheService.Get<string>("sys_wx_accessToken");

+ 4 - 10
Admin.NET/Admin.NET.Core/SqlSugar/SqlSugarSetup.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -133,10 +133,7 @@ public static class SqlSugarSetup
             {
                 if (ex.Parametres == null) return;
                 var log = $"【{DateTime.Now}——错误SQL】\r\n{UtilMethods.GetNativeSql(ex.Sql, (SugarParameter[])ex.Parametres)}\r\n";
-                var originColor = Console.ForegroundColor;
-                Console.ForegroundColor = ConsoleColor.DarkRed;
-                Console.WriteLine(log);
-                Console.ForegroundColor = originColor;
+                Log.Error(log, ex);
                 App.PrintToMiniProfiler("SqlSugar", "Error", log);
             };
             db.Aop.OnLogExecuted = (sql, pars) =>
@@ -156,10 +153,7 @@ public static class SqlSugarSetup
                     var fileLine = db.Ado.SqlStackTrace.FirstLine; // 行号
                     var firstMethodName = db.Ado.SqlStackTrace.FirstMethodName; // 方法名
                     var log = $"【{DateTime.Now}——超时SQL】\r\n【所在文件名】:{fileName}\r\n【代码行数】:{fileLine}\r\n【方法名】:{firstMethodName}\r\n" + $"【SQL语句】:{UtilMethods.GetNativeSql(sql, pars)}";
-                    var originColor = Console.ForegroundColor;
-                    Console.ForegroundColor = ConsoleColor.DarkYellow;
-                    Console.WriteLine(log);
-                    Console.ForegroundColor = originColor;
+                    Log.Warning(log);
                     App.PrintToMiniProfiler("SqlSugar", "Slow", log);
                 }
             };
@@ -171,7 +165,7 @@ public static class SqlSugarSetup
             if (entityInfo.OperationType == DataFilterType.InsertByObject)
             {
                 // 若主键是长整型且空则赋值雪花Id
-                if (entityInfo.EntityColumnInfo.IsPrimarykey && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long))
+                if (entityInfo.EntityColumnInfo.IsPrimarykey && !entityInfo.EntityColumnInfo.IsIdentity && entityInfo.EntityColumnInfo.PropertyInfo.PropertyType == typeof(long))
                 {
                     var id = entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue);
                     if (id == null || (long)id == 0)

+ 20 - 21
Admin.NET/Admin.NET.Core/Util/CommonUtil.cs

@@ -9,7 +9,6 @@ using Magicodes.ExporterAndImporter.Core.Models;
 using System.Xml;
 using System.Xml.Linq;
 using System.Xml.Serialization;
-using UAParser;
 
 namespace Admin.NET.Core;
 
@@ -277,25 +276,25 @@ public static class CommonUtil
         // 整理导入对象的属性名称,<字典数据,原属性信息,目标属性信息>
         var propMappings = new Dictionary<string, Tuple<Dictionary<string, object>, PropertyInfo, PropertyInfo>>();
 
-        var dictService = App.GetService<SqlSugarRepository<SysDictData>>();
+        var dictService = App.GetRequiredService<SqlSugarRepository<SysDictData>>();
         var tSourceProps = typeof(TSource).GetProperties().ToList();
-        var tTargetProps = typeof(TTarget).GetProperties().ToDictionary(m => m.Name);
+        var tTargetProps = typeof(TTarget).GetProperties().ToDictionary(u => u.Name);
         foreach (var propertyInfo in tSourceProps)
         {
             var attrs = propertyInfo.GetCustomAttribute<ImportDictAttribute>();
             if (attrs != null && !string.IsNullOrWhiteSpace(attrs.TypeCode))
             {
                 var targetProp = tTargetProps[attrs.TargetPropName];
-                var mappingValues = dictService.Context.Queryable<SysDictType, SysDictData>((a, b) =>
-                    new JoinQueryInfos(JoinType.Inner, a.Id == b.DictTypeId))
-                    .Where(a => a.Code == attrs.TypeCode)
-                    .Where((a, b) => a.Status == StatusEnum.Enable && b.Status == StatusEnum.Enable)
-                    .Select((a, b) => new
+                var mappingValues = dictService.Context.Queryable<SysDictType, SysDictData>((u, a) =>
+                    new JoinQueryInfos(JoinType.Inner, u.Id == a.DictTypeId))
+                    .Where(u => u.Code == attrs.TypeCode)
+                    .Where((u, a) => u.Status == StatusEnum.Enable && a.Status == StatusEnum.Enable)
+                    .Select((u, a) => new
                     {
-                        Label = b.Value,
-                        Value = b.Code
+                        Label = a.Value,
+                        Value = a.Code
                     }).ToList()
-                    .ToDictionary(m => m.Label, m => m.Value.ParseTo(targetProp.PropertyType));
+                    .ToDictionary(u => u.Label, u => u.Value.ParseTo(targetProp.PropertyType));
                 propMappings.Add(propertyInfo.Name, new Tuple<Dictionary<string, object>, PropertyInfo, PropertyInfo>(mappingValues, propertyInfo, targetProp));
             }
             else
@@ -319,25 +318,25 @@ public static class CommonUtil
         // 整理导入对象的属性名称,<字典数据,原属性信息,目标属性信息>
         var propMappings = new Dictionary<string, Tuple<Dictionary<object, string>, PropertyInfo, PropertyInfo>>();
 
-        var dictService = App.GetService<SqlSugarRepository<SysDictData>>();
+        var dictService = App.GetRequiredService<SqlSugarRepository<SysDictData>>();
         var targetProps = typeof(TTarget).GetProperties().ToList();
-        var sourceProps = typeof(TSource).GetProperties().ToDictionary(m => m.Name);
+        var sourceProps = typeof(TSource).GetProperties().ToDictionary(u => u.Name);
         foreach (var propertyInfo in targetProps)
         {
             var attrs = propertyInfo.GetCustomAttribute<ImportDictAttribute>();
             if (attrs != null && !string.IsNullOrWhiteSpace(attrs.TypeCode))
             {
                 var targetProp = sourceProps[attrs.TargetPropName];
-                var mappingValues = dictService.Context.Queryable<SysDictType, SysDictData>((a, b) =>
-                    new JoinQueryInfos(JoinType.Inner, a.Id == b.DictTypeId))
-                    .Where(a => a.Code == attrs.TypeCode)
-                    .Where((a, b) => a.Status == StatusEnum.Enable && b.Status == StatusEnum.Enable)
-                    .Select((a, b) => new
+                var mappingValues = dictService.Context.Queryable<SysDictType, SysDictData>((u, a) =>
+                    new JoinQueryInfos(JoinType.Inner, u.Id == a.DictTypeId))
+                    .Where(u => u.Code == attrs.TypeCode)
+                    .Where((u, a) => u.Status == StatusEnum.Enable && a.Status == StatusEnum.Enable)
+                    .Select((u, a) => new
                     {
-                        Label = b.Value,
-                        Value = b.Code
+                        Label = a.Value,
+                        Value = a.Code
                     }).ToList()
-                    .ToDictionary(m => m.Value.ParseTo(targetProp.PropertyType), m => m.Label);
+                    .ToDictionary(u => u.Value.ParseTo(targetProp.PropertyType), u => u.Label);
                 propMappings.Add(propertyInfo.Name, new Tuple<Dictionary<object, string>, PropertyInfo, PropertyInfo>(mappingValues, targetProp, propertyInfo));
             }
             else

+ 10 - 3
Admin.NET/Admin.NET.Core/Util/ComputerUtil.cs

@@ -148,9 +148,16 @@ public static class ComputerUtil
     public static string GetIpFromOnline()
     {
         var url = "https://www.ip.cn/api/index?ip&type=0";
-        var str = url.GetAsStringAsync().GetAwaiter().GetResult();
-        var resp = JSON.Deserialize<IpCnResp>(str);
-        return resp.Ip + " " + resp.Address;
+        try
+        {
+            var str = url.GetAsStringAsync().GetAwaiter().GetResult();
+            var resp = JSON.Deserialize<IpCnResp>(str);
+            return resp.Ip + " " + resp.Address;
+        }
+        catch
+        {
+            return "";
+        }
     }
 
     public static bool IsUnix()

+ 2 - 0
Admin.NET/Admin.NET.Core/Util/VerifyFileExtensionName.cs

@@ -61,11 +61,13 @@ public static class VerifyFileExtensionName
         // 压缩包
         dics_ext.Add("52617221", ".rar");
         dics_ext.Add("504B03040A000000", ".zip");
+        dics_ext.Add("504B030414000000", ".zip");
         dics_ext.Add("1F8B08", ".gz");
 
         // 程序文件
         dics_ext.Add("3C3F786D6C", ".xml");
         dics_ext.Add("68746D6C3E", ".html");
+		dics_ext.Add("04034b50", ".apk");
         //dics_ext.Add("7061636B", ".java");
         //dics_ext.Add("3C254020", ".jsp");
         //dics_ext.Add("4D5A9000", ".exe");

+ 16 - 4
Admin.NET/Admin.NET.Web.Core/Startup.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -8,6 +8,7 @@ using Admin.NET.Core;
 using Admin.NET.Core.Service;
 using AspNetCoreRateLimit;
 using Furion;
+using Furion.Logging;
 using Furion.SpecificationDocument;
 using Furion.VirtualFileServer;
 using IGeekFan.AspNetCore.Knife4jUI;
@@ -123,15 +124,23 @@ public class Startup : AppStartup
             options.LogEnabled = false;
             // 事件执行器(失败重试)
             options.AddExecutor<RetryEventHandlerExecutor>();
+            // 事件执行器(重试后依然处理未处理异常的处理器)
+            options.UnobservedTaskExceptionHandler = (obj, args) =>
+            {
+                if (args.Exception?.Message != null)
+                    Log.Error($"EeventBus 有未处理异常 :{args.Exception?.Message} ", args.Exception);
+            };
+            // 事件执行器-监视器(每一次处理都会进入)
+            options.AddMonitor<EventHandlerMonitor>();
 
             #region Redis消息队列
 
             //// 替换事件源存储器
             //options.ReplaceStorer(serviceProvider =>
             //{
-            //    var redisCache = serviceProvider.GetRequiredService<ICache>();
+            //    var cacheProvider = serviceProvider.GetRequiredService<NewLife.Caching.ICacheProvider>();
             //    // 创建默认内存通道事件源对象,可自定义队列路由key,如:adminnet
-            //    return new RedisEventSourceStorer(redisCache, "adminnet", 3000);
+            //    return new RedisEventSourceStorer(cacheProvider, "adminnet", 3000);
             //});
 
             #endregion Redis消息队列
@@ -168,8 +177,11 @@ public class Startup : AppStartup
         services.AddViewEngine();
 
         // 即时通讯
-        services.AddSignalR(SetNewtonsoftJsonSetting);
         //services.AddSingleton<IUserIdProvider, UserIdProvider>();
+        services.AddSignalR(options =>
+        {
+            options.KeepAliveInterval = TimeSpan.FromSeconds(5);
+        }).AddNewtonsoftJsonProtocol(options => SetNewtonsoftJsonSetting(options.PayloadSerializerSettings));
 
         // 系统日志
         services.AddLoggingSetup();

+ 22 - 13
Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/Service.cs.vm

@@ -25,10 +25,10 @@ namespace @Model.NameSpace;
 [ApiDescriptionSettings(@(@Model.ProjectLastName)Const.GroupName, Order = 100)]
 public class @(@Model.ClassName)Service : IDynamicApiController, ITransient
 {
-    private readonly SqlSugarRepository<@(@Model.ClassName)> _rep;
-    public @(@Model.ClassName)Service(SqlSugarRepository<@(@Model.ClassName)> rep)
+    private readonly SqlSugarRepository<@(@Model.ClassName)> _@(@Model.LowerClassName)Rep;
+    public @(@Model.ClassName)Service(SqlSugarRepository<@(@Model.ClassName)> @(@Model.LowerClassName)Rep)
     {
-        _rep = rep;
+        _@(@Model.LowerClassName)Rep = @(@Model.LowerClassName)Rep;
     }
 
     /// <summary>
@@ -38,12 +38,13 @@ public class @(@Model.ClassName)Service : IDynamicApiController, ITransient
     /// <returns></returns>
     [HttpPost]
     [ApiDescriptionSettings(Name = "Page")]
+    [DisplayName("分页查询@(@Model.BusName)")]
     public async Task<SqlSugarPagedList<@(@Model.ClassName)Output>> Page(@(@Model.ClassName)Input input)
     {
 @if (haveLikeCdt) {
 		@:input.SearchKey = input.SearchKey?.Trim();
 }
-        var query = _rep.AsQueryable()
+        var query = _@(@Model.LowerClassName)Rep.AsQueryable()
 @{string conditionFlag = "";}
 @if (haveLikeCdt) {
             @:.WhereIF(!string.IsNullOrEmpty(input.SearchKey), u =>
@@ -120,10 +121,11 @@ if (@column.QueryWhether == "Y"){
     /// <returns></returns>
     [HttpPost]
     [ApiDescriptionSettings(Name = "Add")]
+    [DisplayName("增加@(@Model.BusName)")]
     public async Task<long> Add(Add@(@Model.ClassName)Input input)
     {
         var entity = input.Adapt<@(@Model.ClassName)>();
-        await _rep.InsertAsync(entity);
+        await _@(@Model.LowerClassName)Rep.InsertAsync(entity);
         return entity.Id;
     }
 
@@ -134,15 +136,16 @@ if (@column.QueryWhether == "Y"){
     /// <returns></returns>
     [HttpPost]
     [ApiDescriptionSettings(Name = "Delete")]
+    [DisplayName("删除@(@Model.BusName)")]
     public async Task Delete(Delete@(@Model.ClassName)Input input)
     {
 @foreach (var column in Model.TableField){
 if (@column.ColumnKey == "True"){
-        @:var entity = await _rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
+        @:var entity = await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName)) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
 }
 }
-        await _rep.FakeDeleteAsync(entity);   //假删除
-        //await _rep.DeleteAsync(entity);   //真删除
+        await _@(@Model.LowerClassName)Rep.FakeDeleteAsync(entity);   //假删除
+        //await _@(@Model.LowerClassName)Rep.DeleteAsync(entity);   //真删除
     }
 
     /// <summary>
@@ -152,10 +155,11 @@ if (@column.ColumnKey == "True"){
     /// <returns></returns>
     [HttpPost]
     [ApiDescriptionSettings(Name = "Update")]
+    [DisplayName("更新@(@Model.BusName)")]
     public async Task Update(Update@(@Model.ClassName)Input input)
     {
         var entity = input.Adapt<@(@Model.ClassName)>();
-        await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
+        await _@(@Model.LowerClassName)Rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
     }
 
     /// <summary>
@@ -165,11 +169,12 @@ if (@column.ColumnKey == "True"){
     /// <returns></returns>
     [HttpGet]
     [ApiDescriptionSettings(Name = "Detail")]
+    [DisplayName("获取@(@Model.BusName)")]
     public async Task<@(@Model.ClassName)> Detail([FromQuery] QueryById@(@Model.ClassName)Input input)
     {
 @foreach (var column in Model.TableField){
 if (@column.ColumnKey == "True"){
-        @:return await _rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName));
+        @:return await _@(@Model.LowerClassName)Rep.GetFirstAsync(u => u.@(@column.PropertyName) == input.@(@column.PropertyName));
 }   
 }            
     }
@@ -181,9 +186,10 @@ if (@column.ColumnKey == "True"){
     /// <returns></returns>
     [HttpGet]
     [ApiDescriptionSettings(Name = "List")]
+    [DisplayName("获取@(@Model.BusName)列表")]
     public async Task<List<@(@Model.ClassName)Output>> List([FromQuery] @(@Model.ClassName)Input input)
     {
-        return await _rep.AsQueryable().Select<@(@Model.ClassName)Output>().ToListAsync();
+        return await _@(@Model.LowerClassName)Rep.AsQueryable().Select<@(@Model.ClassName)Output>().ToListAsync();
     }
 
 @foreach (var column in Model.TableField){
@@ -193,9 +199,10 @@ if(@column.EffectType == "fk" && (@column.WhetherAddUpdate == "Y" || column.Quer
     @:/// </summary>
     @:/// <returns></returns>
     @:[ApiDescriptionSettings(Name = "@(@column.FkEntityName)@(@column.PropertyName)Dropdown"), HttpGet]
+    @:[DisplayName("获取@(@column.ColumnComment)列表")]
     @:public async Task<dynamic> @(@column.FkEntityName)@(@column.PropertyName)Dropdown()
     @:{
-        @:return await _rep.Context.Queryable<@(@column.FkEntityName)>()
+        @:return await _@(@Model.LowerClassName)Rep.Context.Queryable<@(@column.FkEntityName)>()
                 @:.Select(u => new
                 @:{
                     @:Label = u.@(@column.FkColumnName),
@@ -214,6 +221,7 @@ if(@column.EffectType == "Upload"){
     @:/// <param name="file"></param>
     @:/// <returns></returns>
     @:[ApiDescriptionSettings(Name = "Upload@(@column.PropertyName)"), HttpPost]
+    @:[DisplayName("上传@(@column.ColumnComment)")]
     @:public async Task<SysFile> Upload@(@column.PropertyName)([Required] IFormFile file)
     @:{
             @:var service = App.GetRequiredService<SysFileService>();
@@ -227,9 +235,10 @@ if(@column.EffectType == "Upload"){
 if(@column.EffectType == "ApiTreeSelect" && !definedObjects.ContainsKey("@(@column.FkEntityName)Tree")){
     @{definedObjects.Add("@(@column.FkEntityName)Tree", 1);}
     @:[HttpGet("@(@column.FkEntityName)Tree")]
+    @:[DisplayName("获取@(@column.FkEntityName)Tree")]
     @:public async Task<dynamic> @(@column.FkEntityName)Tree()
     @:{
-        @:return await _rep.Context.Queryable<@(@column.FkEntityName)>().ToTreeAsync(u => u.Children, u => u.@(@column.PidColumn), 0);
+        @:return await _@(@Model.LowerClassName)Rep.Context.Queryable<@(@column.FkEntityName)>().ToTreeAsync(u => u.Children, u => u.@(@column.PidColumn), 0);
     @:}
 }
 }

+ 2 - 2
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"

+ 1 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ApprovalFlow/Middleware/ApprovalFlowMiddleware.cs

@@ -39,7 +39,7 @@ public class ApprovalFlowMiddleware
 
     public async Task Invoke(HttpContext context)
     {
-        //await App.GetService<SysApprovalService>().MatchApproval(context);
+        // await App.GetRequiredService<SysApprovalService>().MatchApproval(context);
 
         await _next.Invoke(context);
     }

+ 2 - 1
Admin.NET/Plugins/Admin.NET.Plugin.GoView/Entity/GoViewPro.cs

@@ -1,4 +1,4 @@
-// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
 //
 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
 //
@@ -10,6 +10,7 @@ namespace Admin.NET.Plugin.GoView;
 /// GoView 项目表
 /// </summary>
 [SugarTable(null, "GoView 项目表")]
+[SysTable]
 public class GoViewPro : EntityTenant
 {
     /// <summary>

+ 1 - 0
Admin.NET/Plugins/Admin.NET.Plugin.GoView/Entity/GoViewProData.cs

@@ -10,6 +10,7 @@ namespace Admin.NET.Plugin.GoView;
 /// GoView 项目数据表
 /// </summary>
 [SugarTable(null, "GoView 项目数据表")]
+[SysTable]
 public class GoViewProData : EntityTenant
 {
     /// <summary>

+ 1 - 1
Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj

@@ -24,7 +24,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="Rezero.Api" Version="1.7.7" />
+    <PackageReference Include="Rezero.Api" Version="1.7.8" />
   </ItemGroup>
 
   <ItemGroup>

+ 9 - 9
Web/package.json

@@ -2,7 +2,7 @@
 	"name": "admin.net",
 	"type": "module",
 	"version": "2.4.33",
-	"lastBuildTime": "2024.6.28",
+	"lastBuildTime": "2024.07.02",
 	"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
 	"author": "zuohuaijun",
 	"license": "MIT",
@@ -46,8 +46,8 @@
 		"print-js": "^1.6.0",
 		"push.js": "^1.0.12",
 		"qrcodejs2-fixes": "^0.0.2",
-		"qs": "^6.12.1",
-		"relation-graph": "^2.2.1",
+		"qs": "^6.12.2",
+		"relation-graph": "^2.2.2",
 		"screenfull": "^6.0.2",
 		"sm-crypto-v2": "^1.9.0",
 		"sortablejs": "^1.15.2",
@@ -73,23 +73,23 @@
 		"@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",
 		"code-inspector-plugin": "^0.14.2",
-		"eslint": "^9.5.0",
-		"eslint-plugin-vue": "^9.26.0",
+		"eslint": "^9.6.0",
+		"eslint-plugin-vue": "^9.27.0",
 		"less": "^4.2.0",
 		"prettier": "^3.3.2",
 		"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"
 	},

+ 0 - 75
Web/src/api-services/apis/sys-auth-api.ts

@@ -501,49 +501,6 @@ export const SysAuthApiAxiosParamCreator = function (configuration?: Configurati
             let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
             localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
 
-            return {
-                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
-                options: localVarRequestOptions,
-            };
-        },
-        /**
-         * 
-         * @summary 获取水印配置 🔖
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        apiSysAuthWatermarkConfigGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
-            const localVarPath = `/api/sysAuth/watermarkConfig`;
-            // use dummy base URL string because the URL constructor only accepts absolute URLs.
-            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
-            let baseOptions;
-            if (configuration) {
-                baseOptions = configuration.baseOptions;
-            }
-            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
-            const localVarHeaderParameter = {} as any;
-            const localVarQueryParameter = {} as any;
-
-            // authentication Bearer required
-            // http bearer authentication required
-            if (configuration && configuration.accessToken) {
-                const accessToken = typeof configuration.accessToken === 'function'
-                    ? await configuration.accessToken()
-                    : await configuration.accessToken;
-                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
-            }
-
-            const query = new URLSearchParams(localVarUrlObj.search);
-            for (const key in localVarQueryParameter) {
-                query.set(key, localVarQueryParameter[key]);
-            }
-            for (const key in options.params) {
-                query.set(key, options.params[key]);
-            }
-            localVarUrlObj.search = (new URLSearchParams(query)).toString();
-            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
-            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
-
             return {
                 url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
                 options: localVarRequestOptions,
@@ -694,19 +651,6 @@ export const SysAuthApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
-        /**
-         * 
-         * @summary 获取水印配置 🔖
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        async apiSysAuthWatermarkConfigGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
-            const localVarAxiosArgs = await SysAuthApiAxiosParamCreator(configuration).apiSysAuthWatermarkConfigGet(options);
-            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
-                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
-                return axios.request(axiosRequestArgs);
-            };
-        },
     }
 };
 
@@ -812,15 +756,6 @@ export const SysAuthApiFactory = function (configuration?: Configuration, basePa
         async apiSysAuthUserInfoGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultLoginUserOutput>> {
             return SysAuthApiFp(configuration).apiSysAuthUserInfoGet(options).then((request) => request(axios, basePath));
         },
-        /**
-         * 
-         * @summary 获取水印配置 🔖
-         * @param {*} [options] Override http request option.
-         * @throws {RequiredError}
-         */
-        async apiSysAuthWatermarkConfigGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
-            return SysAuthApiFp(configuration).apiSysAuthWatermarkConfigGet(options).then((request) => request(axios, basePath));
-        },
     };
 };
 
@@ -937,14 +872,4 @@ export class SysAuthApi extends BaseAPI {
     public async apiSysAuthUserInfoGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultLoginUserOutput>> {
         return SysAuthApiFp(this.configuration).apiSysAuthUserInfoGet(options).then((request) => request(this.axios, this.basePath));
     }
-    /**
-     * 
-     * @summary 获取水印配置 🔖
-     * @param {*} [options] Override http request option.
-     * @throws {RequiredError}
-     * @memberof SysAuthApi
-     */
-    public async apiSysAuthWatermarkConfigGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
-        return SysAuthApiFp(this.configuration).apiSysAuthWatermarkConfigGet(options).then((request) => request(this.axios, this.basePath));
-    }
 }

+ 100 - 8
Web/src/api-services/apis/sys-config-api.ts

@@ -23,6 +23,7 @@ import { AdminResultListSysConfig } from '../models';
 import { AdminResultObject } from '../models';
 import { AdminResultSqlSugarPagedListSysConfig } from '../models';
 import { AdminResultSysConfig } from '../models';
+import { BatchConfigInput } from '../models';
 import { DeleteConfigInput } from '../models';
 import { InfoSaveInput } from '../models';
 import { PageConfigInput } from '../models';
@@ -129,6 +130,54 @@ export const SysConfigApiAxiosParamCreator = function (configuration?: Configura
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 批量更新参数配置值
+         * @param {Array<BatchConfigInput>} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysConfigBatchUpdatePost: async (body?: Array<BatchConfigInput>, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysConfig/batchUpdate`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
         /**
          * 
          * @summary 删除参数配置 🔖
@@ -275,10 +324,11 @@ export const SysConfigApiAxiosParamCreator = function (configuration?: Configura
         /**
          * 
          * @summary 获取参数配置列表 🔖
+         * @param {PageConfigInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        apiSysConfigListGet: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+        apiSysConfigListPost: async (body?: PageConfigInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
             const localVarPath = `/api/sysConfig/list`;
             // use dummy base URL string because the URL constructor only accepts absolute URLs.
             const localVarUrlObj = new URL(localVarPath, 'https://example.com');
@@ -286,7 +336,7 @@ export const SysConfigApiAxiosParamCreator = function (configuration?: Configura
             if (configuration) {
                 baseOptions = configuration.baseOptions;
             }
-            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
             const localVarHeaderParameter = {} as any;
             const localVarQueryParameter = {} as any;
 
@@ -299,6 +349,8 @@ export const SysConfigApiAxiosParamCreator = function (configuration?: Configura
                 localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
             }
 
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
             const query = new URLSearchParams(localVarUrlObj.search);
             for (const key in localVarQueryParameter) {
                 query.set(key, localVarQueryParameter[key]);
@@ -309,6 +361,8 @@ export const SysConfigApiAxiosParamCreator = function (configuration?: Configura
             localVarUrlObj.search = (new URLSearchParams(query)).toString();
             let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
             localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
 
             return {
                 url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
@@ -539,6 +593,20 @@ export const SysConfigApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 批量更新参数配置值
+         * @param {Array<BatchConfigInput>} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysConfigBatchUpdatePost(body?: Array<BatchConfigInput>, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysConfigApiAxiosParamCreator(configuration).apiSysConfigBatchUpdatePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 删除参数配置 🔖
@@ -583,11 +651,12 @@ export const SysConfigApiFp = function(configuration?: Configuration) {
         /**
          * 
          * @summary 获取参数配置列表 🔖
+         * @param {PageConfigInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysConfigListGet(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysConfig>>> {
-            const localVarAxiosArgs = await SysConfigApiAxiosParamCreator(configuration).apiSysConfigListGet(options);
+        async apiSysConfigListPost(body?: PageConfigInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysConfig>>> {
+            const localVarAxiosArgs = await SysConfigApiAxiosParamCreator(configuration).apiSysConfigListPost(body, options);
             return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
                 const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
                 return axios.request(axiosRequestArgs);
@@ -677,6 +746,16 @@ export const SysConfigApiFactory = function (configuration?: Configuration, base
         async apiSysConfigBatchDeletePost(body?: Array<number>, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
             return SysConfigApiFp(configuration).apiSysConfigBatchDeletePost(body, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 批量更新参数配置值
+         * @param {Array<BatchConfigInput>} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysConfigBatchUpdatePost(body?: Array<BatchConfigInput>, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysConfigApiFp(configuration).apiSysConfigBatchUpdatePost(body, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 删除参数配置 🔖
@@ -709,11 +788,12 @@ export const SysConfigApiFactory = function (configuration?: Configuration, base
         /**
          * 
          * @summary 获取参数配置列表 🔖
+         * @param {PageConfigInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysConfigListGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysConfig>> {
-            return SysConfigApiFp(configuration).apiSysConfigListGet(options).then((request) => request(axios, basePath));
+        async apiSysConfigListPost(body?: PageConfigInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysConfig>> {
+            return SysConfigApiFp(configuration).apiSysConfigListPost(body, options).then((request) => request(axios, basePath));
         },
         /**
          * 
@@ -786,6 +866,17 @@ export class SysConfigApi extends BaseAPI {
     public async apiSysConfigBatchDeletePost(body?: Array<number>, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
         return SysConfigApiFp(this.configuration).apiSysConfigBatchDeletePost(body, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 批量更新参数配置值
+     * @param {Array<BatchConfigInput>} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysConfigApi
+     */
+    public async apiSysConfigBatchUpdatePost(body?: Array<BatchConfigInput>, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysConfigApiFp(this.configuration).apiSysConfigBatchUpdatePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 删除参数配置 🔖
@@ -821,12 +912,13 @@ export class SysConfigApi extends BaseAPI {
     /**
      * 
      * @summary 获取参数配置列表 🔖
+     * @param {PageConfigInput} [body] 
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
      * @memberof SysConfigApi
      */
-    public async apiSysConfigListGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysConfig>> {
-        return SysConfigApiFp(this.configuration).apiSysConfigListGet(options).then((request) => request(this.axios, this.basePath));
+    public async apiSysConfigListPost(body?: PageConfigInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysConfig>> {
+        return SysConfigApiFp(this.configuration).apiSysConfigListPost(body, options).then((request) => request(this.axios, this.basePath));
     }
     /**
      * 

+ 96 - 0
Web/src/api-services/apis/sys-sms-api.ts

@@ -72,6 +72,64 @@ export const SysSmsApiAxiosParamCreator = function (configuration?: Configuratio
                 options: localVarRequestOptions,
             };
         },
+        /**
+         * 
+         * @summary 发送短信模板
+         * @param {any} body 
+         * @param {string} phoneNumber 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysSmsAliyunSendSmsTemplatePhoneNumberPost: async (body: any, phoneNumber: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'body' is not null or undefined
+            if (body === null || body === undefined) {
+                throw new RequiredError('body','Required parameter body was null or undefined when calling apiSysSmsAliyunSendSmsTemplatePhoneNumberPost.');
+            }
+            // verify required parameter 'phoneNumber' is not null or undefined
+            if (phoneNumber === null || phoneNumber === undefined) {
+                throw new RequiredError('phoneNumber','Required parameter phoneNumber was null or undefined when calling apiSysSmsAliyunSendSmsTemplatePhoneNumberPost.');
+            }
+            const localVarPath = `/api/sysSms/aliyunSendSmsTemplate/{phoneNumber}`
+                .replace(`{${"phoneNumber"}}`, encodeURIComponent(String(phoneNumber)));
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
         /**
          * 
          * @summary 发送短信 📨
@@ -193,6 +251,21 @@ export const SysSmsApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 发送短信模板
+         * @param {any} body 
+         * @param {string} phoneNumber 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body: any, phoneNumber: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysSmsApiAxiosParamCreator(configuration).apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body, phoneNumber, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
          * 
          * @summary 发送短信 📨
@@ -240,6 +313,17 @@ export const SysSmsApiFactory = function (configuration?: Configuration, basePat
         async apiSysSmsAliyunSendSmsPhoneNumberPost(phoneNumber: string, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
             return SysSmsApiFp(configuration).apiSysSmsAliyunSendSmsPhoneNumberPost(phoneNumber, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 发送短信模板
+         * @param {any} body 
+         * @param {string} phoneNumber 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body: any, phoneNumber: string, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysSmsApiFp(configuration).apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body, phoneNumber, options).then((request) => request(axios, basePath));
+        },
         /**
          * 
          * @summary 发送短信 📨
@@ -281,6 +365,18 @@ export class SysSmsApi extends BaseAPI {
     public async apiSysSmsAliyunSendSmsPhoneNumberPost(phoneNumber: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
         return SysSmsApiFp(this.configuration).apiSysSmsAliyunSendSmsPhoneNumberPost(phoneNumber, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 发送短信模板
+     * @param {any} body 
+     * @param {string} phoneNumber 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysSmsApi
+     */
+    public async apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body: any, phoneNumber: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysSmsApiFp(this.configuration).apiSysSmsAliyunSendSmsTemplatePhoneNumberPost(body, phoneNumber, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
      * 
      * @summary 发送短信 📨

+ 529 - 22
Web/src/api-services/apis/sys-wechat-pay-api.ts

@@ -17,10 +17,17 @@ import { Configuration } from '../configuration';
 // Some imports not used depending on template conditions
 // @ts-ignore
 import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
+import { AdminResultListSysWechatRefund } from '../models';
 import { AdminResultObject } from '../models';
+import { AdminResultSqlSugarPagedListSysWechatPay } from '../models';
 import { AdminResultSysWechatPay } from '../models';
+import { AdminResultSysWechatRefund } from '../models';
 import { AdminResultWechatPayOutput } from '../models';
+import { AdminResultWechatPayParaOutput } from '../models';
+import { AdminResultWechatPayTransactionOutput } from '../models';
+import { WechatPayPageInput } from '../models';
 import { WechatPayParaInput } from '../models';
+import { WechatPayRefundDomesticInput } from '../models';
 import { WechatPayTransactionInput } from '../models';
 /**
  * SysWechatPayApi - axios parameter creator
@@ -78,7 +85,103 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config
         },
         /**
          * 
-         * @summary 微信支付成功回调(商户直连) 🔖
+         * @summary 查询退款信息列表
+         * @param {string} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayListRefundPost: async (body?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysWechatPay/listRefund`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 分页查询支付列表 🔖
+         * @param {WechatPayPageInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayPagePost: async (body?: WechatPayPageInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysWechatPay/page`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 微信支付成功回调(商户直连)
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
@@ -121,7 +224,56 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config
         },
         /**
          * 
-         * @summary 获取支付订单详情 🔖
+         * @summary 获取支付订单详情(微信接口) 🔖
+         * @param {string} tradeId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayPayInfoFromWechatTradeIdGet: async (tradeId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'tradeId' is not null or undefined
+            if (tradeId === null || tradeId === undefined) {
+                throw new RequiredError('tradeId','Required parameter tradeId was null or undefined when calling apiSysWechatPayPayInfoFromWechatTradeIdGet.');
+            }
+            const localVarPath = `/api/sysWechatPay/payInfoFromWechat/{tradeId}`
+                .replace(`{${"tradeId"}}`, encodeURIComponent(String(tradeId)));
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 获取支付订单详情(本地库) 🔖
          * @param {string} tradeId 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -213,7 +365,7 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(服务商模式) 🔖
+         * @summary 微信支付下单(服务商模式) 🔖
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -261,7 +413,55 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(商户直连) 🔖
+         * @summary 微信支付下单(商户直连)Native
+         * @param {WechatPayTransactionInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayPayTransactionNativePost: async (body?: WechatPayTransactionInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysWechatPay/payTransactionNative`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 微信支付下单(商户直连) 🔖
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -302,6 +502,103 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config
             const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
             localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
 
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 退款申请
+         * @param {WechatPayRefundDomesticInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayRefundDomesticPost: async (body?: WechatPayRefundDomesticInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysWechatPay/refundDomestic`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
+        /**
+         * 
+         * @summary 获取退款订单详情(微信接口)
+         * @param {string} refundId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysWechatPayRefundInfoFromWechatRefundIdGet: async (refundId: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            // verify required parameter 'refundId' is not null or undefined
+            if (refundId === null || refundId === undefined) {
+                throw new RequiredError('refundId','Required parameter refundId was null or undefined when calling apiSysWechatPayRefundInfoFromWechatRefundIdGet.');
+            }
+            const localVarPath = `/api/sysWechatPay/refundInfoFromWechat/{refundId}`
+                .replace(`{${"refundId"}}`, encodeURIComponent(String(refundId)));
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'GET', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
             return {
                 url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
                 options: localVarRequestOptions,
@@ -323,7 +620,7 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) {
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
+        async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultWechatPayParaOutput>>> {
             const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayGenerateParametersForJsapiPayPost(body, options);
             return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
                 const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
@@ -332,7 +629,35 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 微信支付成功回调(商户直连) 🔖
+         * @summary 查询退款信息列表
+         * @param {string} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayListRefundPost(body?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultListSysWechatRefund>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayListRefundPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 分页查询支付列表 🔖
+         * @param {WechatPayPageInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPagePost(body?: WechatPayPageInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSqlSugarPagedListSysWechatPay>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPagePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 微信支付成功回调(商户直连)
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
@@ -345,7 +670,21 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 获取支付订单详情 🔖
+         * @summary 获取支付订单详情(微信接口) 🔖
+         * @param {string} tradeId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSysWechatPay>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 获取支付订单详情(本地库) 🔖
          * @param {string} tradeId 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -372,7 +711,7 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(服务商模式) 🔖
+         * @summary 微信支付下单(服务商模式) 🔖
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -386,18 +725,60 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) {
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(商户直连) 🔖
+         * @summary 微信支付下单(商户直连)Native
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
+        async apiSysWechatPayPayTransactionNativePost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayTransactionNativePost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 微信支付下单(商户直连) 🔖
+         * @param {WechatPayTransactionInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultWechatPayTransactionOutput>>> {
             const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayTransactionPost(body, options);
             return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
                 const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
                 return axios.request(axiosRequestArgs);
             };
         },
+        /**
+         * 
+         * @summary 退款申请
+         * @param {WechatPayRefundDomesticInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayRefundDomesticPost(body?: WechatPayRefundDomesticInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundDomesticPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
+        /**
+         * 
+         * @summary 获取退款订单详情(微信接口)
+         * @param {string} refundId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSysWechatRefund>>> {
+            const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
     }
 };
 
@@ -414,12 +795,32 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
+        async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultWechatPayParaOutput>> {
             return SysWechatPayApiFp(configuration).apiSysWechatPayGenerateParametersForJsapiPayPost(body, options).then((request) => request(axios, basePath));
         },
         /**
          * 
-         * @summary 微信支付成功回调(商户直连) 🔖
+         * @summary 查询退款信息列表
+         * @param {string} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayListRefundPost(body?: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultListSysWechatRefund>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayListRefundPost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 分页查询支付列表 🔖
+         * @param {WechatPayPageInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPagePost(body?: WechatPayPageInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSqlSugarPagedListSysWechatPay>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayPagePost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 微信支付成功回调(商户直连)
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
@@ -428,7 +829,17 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b
         },
         /**
          * 
-         * @summary 获取支付订单详情 🔖
+         * @summary 获取支付订单详情(微信接口) 🔖
+         * @param {string} tradeId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSysWechatPay>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 获取支付订单详情(本地库) 🔖
          * @param {string} tradeId 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -447,7 +858,7 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(服务商模式) 🔖
+         * @summary 微信支付下单(服务商模式) 🔖
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
@@ -457,14 +868,44 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b
         },
         /**
          * 
-         * @summary 微信支付统一下单获取Id(商户直连) 🔖
+         * @summary 微信支付下单(商户直连)Native
          * @param {WechatPayTransactionInput} [body] 
          * @param {*} [options] Override http request option.
          * @throws {RequiredError}
          */
-        async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
+        async apiSysWechatPayPayTransactionNativePost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayPayTransactionNativePost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 微信支付下单(商户直连) 🔖
+         * @param {WechatPayTransactionInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultWechatPayTransactionOutput>> {
             return SysWechatPayApiFp(configuration).apiSysWechatPayPayTransactionPost(body, options).then((request) => request(axios, basePath));
         },
+        /**
+         * 
+         * @summary 退款申请
+         * @param {WechatPayRefundDomesticInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayRefundDomesticPost(body?: WechatPayRefundDomesticInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayRefundDomesticPost(body, options).then((request) => request(axios, basePath));
+        },
+        /**
+         * 
+         * @summary 获取退款订单详情(微信接口)
+         * @param {string} refundId 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSysWechatRefund>> {
+            return SysWechatPayApiFp(configuration).apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId, options).then((request) => request(axios, basePath));
+        },
     };
 };
 
@@ -483,12 +924,34 @@ export class SysWechatPayApi extends BaseAPI {
      * @throws {RequiredError}
      * @memberof SysWechatPayApi
      */
-    public async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
+    public async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultWechatPayParaOutput>> {
         return SysWechatPayApiFp(this.configuration).apiSysWechatPayGenerateParametersForJsapiPayPost(body, options).then((request) => request(this.axios, this.basePath));
     }
     /**
      * 
-     * @summary 微信支付成功回调(商户直连) 🔖
+     * @summary 查询退款信息列表
+     * @param {string} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayListRefundPost(body?: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultListSysWechatRefund>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayListRefundPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 分页查询支付列表 🔖
+     * @param {WechatPayPageInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayPagePost(body?: WechatPayPageInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSqlSugarPagedListSysWechatPay>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayPagePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 微信支付成功回调(商户直连)
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
      * @memberof SysWechatPayApi
@@ -498,7 +961,18 @@ export class SysWechatPayApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 获取支付订单详情 🔖
+     * @summary 获取支付订单详情(微信接口) 🔖
+     * @param {string} tradeId 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSysWechatPay>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayInfoFromWechatTradeIdGet(tradeId, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 获取支付订单详情(本地库) 🔖
      * @param {string} tradeId 
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
@@ -519,7 +993,7 @@ export class SysWechatPayApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 微信支付统一下单获取Id(服务商模式) 🔖
+     * @summary 微信支付下单(服务商模式) 🔖
      * @param {WechatPayTransactionInput} [body] 
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
@@ -530,13 +1004,46 @@ export class SysWechatPayApi extends BaseAPI {
     }
     /**
      * 
-     * @summary 微信支付统一下单获取Id(商户直连) 🔖
+     * @summary 微信支付下单(商户直连)Native
      * @param {WechatPayTransactionInput} [body] 
      * @param {*} [options] Override http request option.
      * @throws {RequiredError}
      * @memberof SysWechatPayApi
      */
-    public async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
+    public async apiSysWechatPayPayTransactionNativePost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayTransactionNativePost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 微信支付下单(商户直连) 🔖
+     * @param {WechatPayTransactionInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultWechatPayTransactionOutput>> {
         return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayTransactionPost(body, options).then((request) => request(this.axios, this.basePath));
     }
+    /**
+     * 
+     * @summary 退款申请
+     * @param {WechatPayRefundDomesticInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayRefundDomesticPost(body?: WechatPayRefundDomesticInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundDomesticPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
+    /**
+     * 
+     * @summary 获取退款订单详情(微信接口)
+     * @param {string} refundId 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysWechatPayApi
+     */
+    public async apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSysWechatRefund>> {
+        return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundInfoFromWechatRefundIdGet(refundId, options).then((request) => request(this.axios, this.basePath));
+    }
 }

+ 8 - 8
Web/src/api-services/models/add-org-input.ts

@@ -118,14 +118,6 @@ export interface AddOrgInput {
      */
     level?: number | null;
 
-    /**
-     * 机构类型-数据字典
-     *
-     * @type {string}
-     * @memberof AddOrgInput
-     */
-    type?: string | null;
-
     /**
      * 负责人Id
      *
@@ -179,4 +171,12 @@ export interface AddOrgInput {
      * @memberof AddOrgInput
      */
     name: string;
+
+    /**
+     * 机构类型
+     *
+     * @type {string}
+     * @memberof AddOrgInput
+     */
+    type?: string | null;
 }

+ 71 - 0
Web/src/api-services/models/admin-result-list-sys-wechat-refund.ts

@@ -0,0 +1,71 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { SysWechatRefund } from './sys-wechat-refund';
+ /**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultListSysWechatRefund
+ */
+export interface AdminResultListSysWechatRefund {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    message?: string | null;
+
+    /**
+     * 数据
+     *
+     * @type {Array<SysWechatRefund>}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    result?: Array<SysWechatRefund> | null;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultListSysWechatRefund
+     */
+    time?: Date;
+}

+ 69 - 0
Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-wechat-pay.ts

@@ -0,0 +1,69 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { SqlSugarPagedListSysWechatPay } from './sql-sugar-paged-list-sys-wechat-pay';
+ /**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultSqlSugarPagedListSysWechatPay
+ */
+export interface AdminResultSqlSugarPagedListSysWechatPay {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    message?: string | null;
+
+    /**
+     * @type {SqlSugarPagedListSysWechatPay}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    result?: SqlSugarPagedListSysWechatPay;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultSqlSugarPagedListSysWechatPay
+     */
+    time?: Date;
+}

+ 69 - 0
Web/src/api-services/models/admin-result-sys-wechat-refund.ts

@@ -0,0 +1,69 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { SysWechatRefund } from './sys-wechat-refund';
+ /**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultSysWechatRefund
+ */
+export interface AdminResultSysWechatRefund {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultSysWechatRefund
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultSysWechatRefund
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultSysWechatRefund
+     */
+    message?: string | null;
+
+    /**
+     * @type {SysWechatRefund}
+     * @memberof AdminResultSysWechatRefund
+     */
+    result?: SysWechatRefund;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultSysWechatRefund
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultSysWechatRefund
+     */
+    time?: Date;
+}

+ 69 - 0
Web/src/api-services/models/admin-result-wechat-pay-para-output.ts

@@ -0,0 +1,69 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { WechatPayParaOutput } from './wechat-pay-para-output';
+ /**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultWechatPayParaOutput
+ */
+export interface AdminResultWechatPayParaOutput {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    message?: string | null;
+
+    /**
+     * @type {WechatPayParaOutput}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    result?: WechatPayParaOutput;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultWechatPayParaOutput
+     */
+    time?: Date;
+}

+ 69 - 0
Web/src/api-services/models/admin-result-wechat-pay-transaction-output.ts

@@ -0,0 +1,69 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { WechatPayTransactionOutput } from './wechat-pay-transaction-output';
+ /**
+ * 全局返回结果
+ *
+ * @export
+ * @interface AdminResultWechatPayTransactionOutput
+ */
+export interface AdminResultWechatPayTransactionOutput {
+
+    /**
+     * 状态码
+     *
+     * @type {number}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    code?: number;
+
+    /**
+     * 类型success、warning、error
+     *
+     * @type {string}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    type?: string | null;
+
+    /**
+     * 错误信息
+     *
+     * @type {string}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    message?: string | null;
+
+    /**
+     * @type {WechatPayTransactionOutput}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    result?: WechatPayTransactionOutput;
+
+    /**
+     * 附加数据
+     *
+     * @type {any}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    extras?: any | null;
+
+    /**
+     * 时间
+     *
+     * @type {Date}
+     * @memberof AdminResultWechatPayTransactionOutput
+     */
+    time?: Date;
+}

+ 38 - 0
Web/src/api-services/models/batch-config-input.ts

@@ -0,0 +1,38 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+ /**
+ * 批量配置参数输入
+ *
+ * @export
+ * @interface BatchConfigInput
+ */
+export interface BatchConfigInput {
+
+    /**
+     * 编码
+     *
+     * @type {string}
+     * @memberof BatchConfigInput
+     */
+    code?: string | null;
+
+    /**
+     * 属性值
+     *
+     * @type {string}
+     * @memberof BatchConfigInput
+     */
+    value?: string | null;
+}

+ 8 - 0
Web/src/api-services/models/enum-entity.ts

@@ -28,6 +28,14 @@ export interface EnumEntity {
      */
     describe?: string | null;
 
+    /**
+     * 枚举的样式
+     *
+     * @type {string}
+     * @memberof EnumEntity
+     */
+    theme?: string | null;
+
     /**
      * 枚举名称
      *

+ 12 - 0
Web/src/api-services/models/index.ts

@@ -54,6 +54,7 @@ export * from './admin-result-list-sys-pos';
 export * from './admin-result-list-sys-region';
 export * from './admin-result-list-sys-user';
 export * from './admin-result-list-sys-user-ext-org';
+export * from './admin-result-list-sys-wechat-refund';
 export * from './admin-result-list-table-output';
 export * from './admin-result-login-output';
 export * from './admin-result-login-user-output';
@@ -79,6 +80,7 @@ export * from './admin-result-sql-sugar-paged-list-sys-plugin';
 export * from './admin-result-sql-sugar-paged-list-sys-print';
 export * from './admin-result-sql-sugar-paged-list-sys-region';
 export * from './admin-result-sql-sugar-paged-list-sys-role';
+export * from './admin-result-sql-sugar-paged-list-sys-wechat-pay';
 export * from './admin-result-sql-sugar-paged-list-sys-wechat-user';
 export * from './admin-result-sql-sugar-paged-list-tenant-output';
 export * from './admin-result-sql-sugar-paged-list-user-output';
@@ -93,13 +95,17 @@ export * from './admin-result-sys-ldap';
 export * from './admin-result-sys-print';
 export * from './admin-result-sys-user';
 export * from './admin-result-sys-wechat-pay';
+export * from './admin-result-sys-wechat-refund';
 export * from './admin-result-visual-db-table';
 export * from './admin-result-wechat-pay-output';
+export * from './admin-result-wechat-pay-para-output';
+export * from './admin-result-wechat-pay-transaction-output';
 export * from './admin-result-wx-open-id-output';
 export * from './admin-result-wx-phone-output';
 export * from './api-output';
 export * from './assembly';
 export * from './base-proc-input';
+export * from './batch-config-input';
 export * from './calendar';
 export * from './calendar-algorithm-type';
 export * from './calendar-week-rule';
@@ -274,6 +280,7 @@ export * from './sql-sugar-paged-list-sys-plugin';
 export * from './sql-sugar-paged-list-sys-print';
 export * from './sql-sugar-paged-list-sys-region';
 export * from './sql-sugar-paged-list-sys-role';
+export * from './sql-sugar-paged-list-sys-wechat-pay';
 export * from './sql-sugar-paged-list-sys-wechat-user';
 export * from './sql-sugar-paged-list-tenant-output';
 export * from './sql-sugar-paged-list-user-output';
@@ -315,6 +322,7 @@ export * from './sys-role';
 export * from './sys-user';
 export * from './sys-user-ext-org';
 export * from './sys-wechat-pay';
+export * from './sys-wechat-refund';
 export * from './sys-wechat-user';
 export * from './table-output';
 export * from './tenant-id-input';
@@ -357,8 +365,12 @@ export * from './visual-column';
 export * from './visual-db-table';
 export * from './visual-table';
 export * from './wechat-pay-output';
+export * from './wechat-pay-page-input';
 export * from './wechat-pay-para-input';
+export * from './wechat-pay-para-output';
+export * from './wechat-pay-refund-domestic-input';
 export * from './wechat-pay-transaction-input';
+export * from './wechat-pay-transaction-output';
 export * from './wechat-user-input';
 export * from './wechat-user-login';
 export * from './wx-open-id-login-input';

+ 8 - 0
Web/src/api-services/models/login-user-output.ts

@@ -154,4 +154,12 @@ export interface LoginUserOutput {
      * @memberof LoginUserOutput
      */
     roleIds?: Array<number> | null;
+
+    /**
+     * 水印文字
+     *
+     * @type {string}
+     * @memberof LoginUserOutput
+     */
+    watermarkText?: string | null;
 }

+ 79 - 0
Web/src/api-services/models/sql-sugar-paged-list-sys-wechat-pay.ts

@@ -0,0 +1,79 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { SysWechatPay } from './sys-wechat-pay';
+ /**
+ * 分页泛型集合
+ *
+ * @export
+ * @interface SqlSugarPagedListSysWechatPay
+ */
+export interface SqlSugarPagedListSysWechatPay {
+
+    /**
+     * 页码
+     *
+     * @type {number}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    page?: number;
+
+    /**
+     * 页容量
+     *
+     * @type {number}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    pageSize?: number;
+
+    /**
+     * 总条数
+     *
+     * @type {number}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    total?: number;
+
+    /**
+     * 总页数
+     *
+     * @type {number}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    totalPages?: number;
+
+    /**
+     * 当前页集合
+     *
+     * @type {Array<SysWechatPay>}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    items?: Array<SysWechatPay> | null;
+
+    /**
+     * 是否有上一页
+     *
+     * @type {boolean}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    hasPrevPage?: boolean;
+
+    /**
+     * 是否有下一页
+     *
+     * @type {boolean}
+     * @memberof SqlSugarPagedListSysWechatPay
+     */
+    hasNextPage?: boolean;
+}

+ 24 - 0
Web/src/api-services/models/sys-wechat-pay.ts

@@ -244,6 +244,30 @@ export interface SysWechatPay {
      */
     openId?: string | null;
 
+    /**
+     * 业务标签,用来区分做什么业务
+     *
+     * @type {string}
+     * @memberof SysWechatPay
+     */
+    tags?: string | null;
+
+    /**
+     * 对应业务的主键
+     *
+     * @type {number}
+     * @memberof SysWechatPay
+     */
+    businessId?: number;
+
+    /**
+     * 付款二维码内容
+     *
+     * @type {string}
+     * @memberof SysWechatPay
+     */
+    qrcodeContent?: string | null;
+
     /**
      * 子商户号
      *

+ 182 - 0
Web/src/api-services/models/sys-wechat-refund.ts

@@ -0,0 +1,182 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+ /**
+ * 系统微信支付退款表
+ *
+ * @export
+ * @interface SysWechatRefund
+ */
+export interface SysWechatRefund {
+
+    /**
+     * 雪花Id
+     *
+     * @type {number}
+     * @memberof SysWechatRefund
+     */
+    id?: number;
+
+    /**
+     * 创建时间
+     *
+     * @type {Date}
+     * @memberof SysWechatRefund
+     */
+    createTime?: Date;
+
+    /**
+     * 更新时间
+     *
+     * @type {Date}
+     * @memberof SysWechatRefund
+     */
+    updateTime?: Date | null;
+
+    /**
+     * 创建者Id
+     *
+     * @type {number}
+     * @memberof SysWechatRefund
+     */
+    createUserId?: number | null;
+
+    /**
+     * 创建者姓名
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    createUserName?: string | null;
+
+    /**
+     * 修改者Id
+     *
+     * @type {number}
+     * @memberof SysWechatRefund
+     */
+    updateUserId?: number | null;
+
+    /**
+     * 修改者姓名
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    updateUserName?: string | null;
+
+    /**
+     * 软删除
+     *
+     * @type {boolean}
+     * @memberof SysWechatRefund
+     */
+    isDelete?: boolean;
+
+    /**
+     * 定单主键
+     *
+     * @type {number}
+     * @memberof SysWechatRefund
+     */
+    wechatPayId?: number;
+
+    /**
+     * 商户退款号
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    outRefundNumber: string;
+
+    /**
+     * 退款订单号
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    transactionId: string;
+
+    /**
+     * 退款原因
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    reason?: string | null;
+
+    /**
+     * 退款渠道
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    channel?: string | null;
+
+    /**
+     * 退款入账账户
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    userReceivedAccount?: string | null;
+
+    /**
+     * 退款状态
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    tradeState?: string | null;
+
+    /**
+     * 交易状态描述
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    tradeStateDescription?: string | null;
+
+    /**
+     * 订单总金额
+     *
+     * @type {number}
+     * @memberof SysWechatRefund
+     */
+    refund?: number;
+
+    /**
+     * 支完成时间
+     *
+     * @type {Date}
+     * @memberof SysWechatRefund
+     */
+    successTime?: Date | null;
+
+    /**
+     * 回调通知地址
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    notifyUrl?: string | null;
+
+    /**
+     * 备注
+     *
+     * @type {string}
+     * @memberof SysWechatRefund
+     */
+    remark?: string | null;
+}

+ 8 - 8
Web/src/api-services/models/update-org-input.ts

@@ -118,14 +118,6 @@ export interface UpdateOrgInput {
      */
     level?: number | null;
 
-    /**
-     * 机构类型-数据字典
-     *
-     * @type {string}
-     * @memberof UpdateOrgInput
-     */
-    type?: string | null;
-
     /**
      * 负责人Id
      *
@@ -179,4 +171,12 @@ export interface UpdateOrgInput {
      * @memberof UpdateOrgInput
      */
     name: string;
+
+    /**
+     * 机构类型
+     *
+     * @type {string}
+     * @memberof UpdateOrgInput
+     */
+    type?: string | null;
 }

+ 76 - 0
Web/src/api-services/models/wechat-pay-page-input.ts

@@ -0,0 +1,76 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+ /**
+ * 
+ *
+ * @export
+ * @interface WechatPayPageInput
+ */
+export interface WechatPayPageInput {
+
+    /**
+     * 当前页码
+     *
+     * @type {number}
+     * @memberof WechatPayPageInput
+     */
+    page?: number;
+
+    /**
+     * 页码容量
+     *
+     * @type {number}
+     * @memberof WechatPayPageInput
+     */
+    pageSize?: number;
+
+    /**
+     * 排序字段
+     *
+     * @type {string}
+     * @memberof WechatPayPageInput
+     */
+    field?: string | null;
+
+    /**
+     * 排序方向
+     *
+     * @type {string}
+     * @memberof WechatPayPageInput
+     */
+    order?: string | null;
+
+    /**
+     * 降序排序
+     *
+     * @type {string}
+     * @memberof WechatPayPageInput
+     */
+    descStr?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayPageInput
+     */
+    searchKey?: string | null;
+
+    /**
+     * 添加时间范围
+     *
+     * @type {Array<Date>}
+     * @memberof WechatPayPageInput
+     */
+    createTimeRange?: Array<Date> | null;
+}

+ 58 - 0
Web/src/api-services/models/wechat-pay-para-output.ts

@@ -0,0 +1,58 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+ /**
+ * 
+ *
+ * @export
+ * @interface WechatPayParaOutput
+ */
+export interface WechatPayParaOutput {
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    appId?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    timeStamp?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    nonceStr?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    _package?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    signType?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayParaOutput
+     */
+    paySign?: string | null;
+}

+ 54 - 0
Web/src/api-services/models/wechat-pay-refund-domestic-input.ts

@@ -0,0 +1,54 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+ /**
+ * 
+ *
+ * @export
+ * @interface WechatPayRefundDomesticInput
+ */
+export interface WechatPayRefundDomesticInput {
+
+    /**
+     * 商户端生成的业务流水号
+     *
+     * @type {string}
+     * @memberof WechatPayRefundDomesticInput
+     */
+    tradeId: string;
+
+    /**
+     * 退款原因
+     *
+     * @type {string}
+     * @memberof WechatPayRefundDomesticInput
+     */
+    reason?: string | null;
+
+    /**
+     * 退款金额
+     *
+     * @type {number}
+     * @memberof WechatPayRefundDomesticInput
+     */
+    refund: number;
+
+    /**
+     * 原订单金额
+     *
+     * @type {number}
+     * @memberof WechatPayRefundDomesticInput
+     */
+    total: number;
+}

+ 16 - 0
Web/src/api-services/models/wechat-pay-transaction-input.ts

@@ -59,4 +59,20 @@ export interface WechatPayTransactionInput {
      * @memberof WechatPayTransactionInput
      */
     goodsTag?: string | null;
+
+    /**
+     * 业务标签,用来区分做什么业务
+     *
+     * @type {string}
+     * @memberof WechatPayTransactionInput
+     */
+    tags?: string | null;
+
+    /**
+     * 对应业务的主键
+     *
+     * @type {number}
+     * @memberof WechatPayTransactionInput
+     */
+    businessId?: number;
 }

+ 41 - 0
Web/src/api-services/models/wechat-pay-transaction-output.ts

@@ -0,0 +1,41 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
+ *
+ * OpenAPI spec version: 1.0.0
+ * 
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import { WechatPayParaOutput } from './wechat-pay-para-output';
+ /**
+ * 
+ *
+ * @export
+ * @interface WechatPayTransactionOutput
+ */
+export interface WechatPayTransactionOutput {
+
+    /**
+     * @type {string}
+     * @memberof WechatPayTransactionOutput
+     */
+    prepayId?: string | null;
+
+    /**
+     * @type {string}
+     * @memberof WechatPayTransactionOutput
+     */
+    outTradeNumber?: string | null;
+
+    /**
+     * @type {WechatPayParaOutput}
+     * @memberof WechatPayTransactionOutput
+     */
+    singInfo?: WechatPayParaOutput;
+}

+ 31 - 0
Web/src/api/system/weChatPay.ts

@@ -0,0 +1,31 @@
+import request from '/@/utils/request';
+enum Api {
+	PagePayList = '/api/sysWechatPay/page',
+	CreatePay = '/api/sysWechatPay/payTransactionNative',
+	GetRefundListByID = '/api/sysWechatPay/listRefund',
+	RefundDomestic = '/api/sysWechatPay/refundDomestic'
+}
+export const pagePayList = (params?: any) =>
+	request({
+		url: Api.PagePayList,
+		method: 'post',
+		data: params,
+	});
+export const createPay = (params?: any) =>
+	request({
+		url: Api.CreatePay,
+		method: 'post',
+		data: params,
+	});
+export const getRefundListByID = (params?: any) =>
+	request({
+		url: Api.GetRefundListByID,
+		method: 'post',
+		data: params,
+	});
+export const refundDomestic = (params?: any) =>
+	request({
+		url: Api.RefundDomestic,
+		method: 'post',
+		data: params,
+	});

+ 1 - 1
Web/src/components/table/index.vue

@@ -117,7 +117,7 @@
 			<el-pagination
 				v-model:current-page="state.page.page"
 				v-model:page-size="state.page.pageSize"
-				small
+				size="small"
 				:pager-count="5"
 				:page-sizes="config.pageSizes"
 				:total="state.total"

+ 11 - 2
Web/src/layout/navBars/topBar/userNews.vue

@@ -29,8 +29,16 @@
 				</div>
 			</el-tab-pane>
 		</el-tabs>
-		<el-dialog v-model="state.dialogVisible" title="消息详情" draggable width="769px">
-			<p v-html="state.content"></p>
+		<el-dialog v-model="state.dialogVisible" draggable width="769px">
+			<template #header>
+				<div style="color: #fff">
+					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Bell /> </el-icon>
+					<span> 消息详情 </span>
+				</div>
+			</template>
+			<div class="w-e-text-container">
+				<div v-html="state.content" data-slate-editor></div>
+			</div>
 			<template #footer>
 				<span class="dialog-footer">
 					<el-button type="primary" @click="state.dialogVisible = false">确认</el-button>
@@ -41,6 +49,7 @@
 </template>
 
 <script setup lang="ts" name="layoutBreadcrumbUserNews">
+import '@wangeditor/editor/dist/css/style.css';
 import { reactive } from 'vue';
 import router from '/@/router';
 import commonFunction from '/@/utils/commonFunction';

+ 8 - 8
Web/src/stores/themeConfig.ts

@@ -10,7 +10,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 			 * 全局主题
 			 */
 			// 默认 primary 主题颜色
-			primary: '#F03F24', //胭脂红:#F03F24 //飞燕草蓝:#0F59A4 //薄荷绿:#207F4C
+			primary: '#0F59A4', //胭脂红:#F03F24 //飞燕草蓝:#0F59A4 //薄荷绿:#207F4C
 			// 是否开启深色模式
 			isIsDark: false,
 
@@ -84,15 +84,15 @@ export const useThemeConfig = defineStore('themeConfig', {
 			// 是否开启 Tagsview
 			isTagsview: true,
 			// 是否开启 Breadcrumb 图标
-			isBreadcrumbIcon: false,
+			isBreadcrumbIcon: true,
 			// 是否开启 Tagsview 图标
-			isTagsviewIcon: false,
+			isTagsviewIcon: true,
 			// 是否开启 TagsView 缓存
-			isCacheTagsView: false,
+			isCacheTagsView: true,
 			// 是否开启 TagsView 拖拽
 			isSortableTagsView: true,
-			// 是否开启 TagsView 共用
-			isShareTagsView: false,
+			// 是否开启 TagsView 共用 -- 共用详情界面:tagsView只会出现一个;非共用详情界面:tagsView会出现多个
+			isShareTagsView: true,
 			// 是否开启 Footer 底部版权信息
 			isFooter: true,
 			// 是否开启灰色模式
@@ -100,7 +100,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 			// 是否开启色弱模式
 			isInvert: false,
 			// 是否开启水印
-			isWatermark: false,
+			isWatermark: true,
 			// 水印文案
 			watermarkText: 'Admin.NET',
 
@@ -123,7 +123,7 @@ export const useThemeConfig = defineStore('themeConfig', {
 			 * 中的 `initSetLayoutChange(设置布局切换,重置主题样式)` 方法
 			 */
 			// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
-			layout: 'columns',
+			layout: 'defaults',
 
 			/**
 			 * 后端控制路由

+ 2 - 1
Web/src/stores/userInfo.ts

@@ -76,7 +76,7 @@ export const useUserInfo = defineStore('userInfo', {
 							idCardNum: d.idCardNum,
 							email: d.email,
 							accountType: d.accountType,
-							avatar: d.avatar ?? '/favicon.ico',
+							avatar: d.avatar ?? '/Upload/logo.png',
 							address: d.address,
 							signature: d.signature,
 							orgId: d.orgId,
@@ -132,6 +132,7 @@ export const useUserInfo = defineStore('userInfo', {
 
 		// 根据字典类型和代码取字典项
 		getDictItemByCode(typePCode: string, val: string) {
+			val = val.toString();
 			if (val) {
 				const _val = val.toString();
 				const ds = this.getDictDatasByCode(typePCode);

+ 28 - 0
Web/src/utils/authFunction.ts

@@ -1,5 +1,6 @@
 import { useUserInfo } from '/@/stores/userInfo';
 import { judgementSameArr } from '/@/utils/arrayOperation';
+import { resolveDirective, withDirectives } from 'vue';
 
 /**
  * 单个权限验证
@@ -36,3 +37,30 @@ export function authAll(value: Array<string>): boolean {
 	const stores = useUserInfo();
 	return judgementSameArr(value, stores.userInfos.authBtnList);
 }
+/**
+ * 单个权限验证,是否满足,返回VNode
+ * @param VNode 元素
+ * @param value 权限值
+ * @returns VNode
+ */
+export function hAuth<T extends VNode>(el: T, value: string): T {
+	return withDirectives(el, [[resolveDirective('auth'), value]]);
+}
+/**
+ * 多个权限验证,判断是否满足一个,返回VNode
+ * @param VNode 元素
+ * @param value 权限值
+ * @returns VNode
+ */
+export function hAuths<T extends VNode>(el: T, value: Array<string>): T {
+	return withDirectives(el, [[resolveDirective('auths'), value]]);
+}
+/**
+ * 多个权限验证,判断是否全部满足,返回VNode
+ * @param VNode 元素
+ * @param value 权限值
+ * @returns VNode
+ */
+export function hAuthAll<T extends VNode>(el: T, value: Array<string>): T {
+	return withDirectives(el, [[resolveDirective('auth-all'), value]]);
+}

+ 2 - 1
Web/src/utils/base64Conver.ts

@@ -79,6 +79,7 @@ export function base64ToFile(dataURL: string, fileName: string, mimeType = null)
  * @param mimeType {String} 文件类型
  * @return {File}
  */
-export function blobToFile(blob: Blob, fileName: string, mimeType: any) {
+export function blobToFile(blob: Blob, fileName: string, mimeType?: string) {
+	if (mimeType == null) mimeType = blob.type;
 	return new File([blob], fileName, { type: mimeType });
 }

+ 1 - 2
Web/src/utils/formatTime.ts

@@ -39,8 +39,7 @@ export function formatDate(date: Date, format: string): string {
 		'3': '三',
 		'4': '四',
 	};
-	if (/(W+)/.test(format))
-		format = format.replace(RegExp.$1, RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]);
+	if (/(W+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length > 1 ? (RegExp.$1.length > 2 ? '星期' + week[we] : '周' + week[we]) : week[we]);
 	if (/(Q+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 4 ? '第' + quarter[qut] + '季度' : quarter[qut]);
 	if (/(Z+)/.test(format)) format = format.replace(RegExp.$1, RegExp.$1.length == 3 ? '第' + z + '周' : z + '');
 	for (let k in opt) {

+ 17 - 0
Web/src/utils/json-utils.ts

@@ -0,0 +1,17 @@
+/**
+ * 尝试将字符串转对象
+ * @param value 要转的字符串
+ * @returns {Object|String}
+ */
+export const StringToObj = (value: any): any => {
+	if (value && typeof value == 'string') {
+		try {
+			const obj = JSON.parse(value);
+			if (typeof obj == 'object') {
+				return obj;
+			} else return value;
+		} catch (e) {
+			return value;
+		}
+	} else return value;
+};

+ 2 - 0
Web/src/utils/storage.ts

@@ -59,6 +59,8 @@ export const Session = {
 	// 移除全部临时缓存
 	clear() {
 		Cookies.remove('token');
+		Cookies.remove('userInfo');
+		Cookies.remove('constList');
 		window.sessionStorage.clear();
 	},
 };

+ 12 - 3
Web/src/views/home/notice/index.vue

@@ -53,15 +53,23 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"
 				layout="total, sizes, prev, pager, next, jumper"
 			/>
 		</el-card>
-		<el-dialog v-model="state.dialogVisible" title="消息详情" draggable width="769px">
-			<p v-html="state.content"></p>
+		<el-dialog v-model="state.dialogVisible" draggable width="769px">
+			<template #header>
+				<div style="color: #fff">
+					<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Bell /> </el-icon>
+					<span> 消息详情 </span>
+				</div>
+			</template>
+			<div class="w-e-text-container">
+				<div v-html="state.content" data-slate-editor></div>
+			</div>
 			<template #footer>
 				<span class="dialog-footer">
 					<el-button type="primary" @click="state.dialogVisible = false">确认</el-button>
@@ -72,6 +80,7 @@
 </template>
 
 <script setup lang="ts" name="notice">
+import '@wangeditor/editor/dist/css/style.css';
 import { onMounted, reactive } from 'vue';
 import commonFunction from '/@/utils/commonFunction';
 

+ 35 - 65
Web/src/views/mqttx/index.vue

@@ -4,7 +4,7 @@
 		<el-card :model="connection">
 			<h1>连接参数(Configuration)</h1>
 			<el-form label-position="top" :model="connection">
-				<el-row :gutter="20">
+				<el-row :gutter="6">
 					<el-col :span="8">
 						<el-form-item prop="host" label="协议|主机|端口">
 							<el-input v-model="connection.host" :disabled="connSuccess" type="password" show-password>
@@ -49,7 +49,6 @@
 						<el-button
 							type="primary"
 							:icon="Setting"
-							size="default"
 							class="sub-btn"
 							:disabled="client.connected"
 							@click="createConnection"
@@ -58,7 +57,7 @@
 						>
 							{{ client.connected ? '已连接(Connected)' : '连接(Connect)' }}
 						</el-button>
-						<el-button v-if="client.connected" type="warning" size="default" :icon="Discount" @click="destroyConnection" :loading="btnLoadingType === 'disconnect'"> 断开(Disconnect) </el-button>
+						<el-button v-if="client.connected" class="sub-btn" type="warning" :icon="Discount" @click="destroyConnection" :loading="btnLoadingType === 'disconnect'"> 断开(Disconnect) </el-button>
 					</el-col>
 				</el-row>
 			</el-form>
@@ -67,7 +66,7 @@
 		<el-card shadow="hover">
 			<h1>订阅(Subscribe)</h1>
 			<el-form label-position="top" :model="subscription">
-				<el-row :gutter="20">
+				<el-row :gutter="6">
 					<el-col :span="12">
 						<el-form-item prop="topic" label="订阅主题(Topic)">
 							<el-input v-model="connection.subTopics" :disabled="subscribedSuccess" type="password" show-password></el-input>
@@ -84,7 +83,6 @@
 						<el-button
 							type="primary"
 							:icon="Connection"
-							size="default"
 							class="sub-btn"
 							:style="{ display: subscribedSuccess ? 'none' : '' }"
 							:loading="btnLoadingType === 'subscribe'"
@@ -93,16 +91,7 @@
 						>
 							{{ subscribedSuccess ? '已订阅(Subscribed)' : '订阅(Subscribe)' }}
 						</el-button>
-						<el-button
-							v-if="subscribedSuccess"
-							type="warning"
-							:icon="Discount"
-							size="default"
-							class="sub-btn"
-							:loading="btnLoadingType === 'unsubscribe'"
-							:disabled="!client.connected"
-							@click="doUnSubscribe"
-						>
+						<el-button v-if="subscribedSuccess" type="warning" :icon="Discount" class="sub-btn" :loading="btnLoadingType === 'unsubscribe'" :disabled="!client.connected" @click="doUnSubscribe">
 							取消(Unsubscribe)
 						</el-button>
 					</el-col>
@@ -113,7 +102,7 @@
 		<el-card shadow="hover">
 			<h1>发布(Publish)</h1>
 			<el-form label-position="top" :model="publish">
-				<el-row :gutter="30">
+				<el-row :gutter="6">
 					<el-col :span="8">
 						<el-form-item prop="topic" label="发布主题(Topic)">
 							<el-input v-model="connection.pubTopic" type="password" show-password></el-input>
@@ -136,7 +125,7 @@
 					</el-col>
 				</el-row>
 
-				<el-row :gutter="30">
+				<el-row :gutter="6">
 					<el-col :span="16">
 						<el-form-item prop="payload" label="操作指令(Payload)">
 							<el-input v-model="publish.payload" clearable maxlength="64" show-word-limit>
@@ -158,15 +147,7 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="8" class="text-right">
-						<el-button
-							type="success"
-							:icon="Position"
-							size="default"
-							class="sub-btn"
-							:loading="btnLoadingType === 'publish'"
-							:disabled="!client.connected"
-							@click="doPublish(publish.payload, connection.pubTopic)"
-						>
+						<el-button type="success" :icon="Position" class="sub-btn" :loading="btnLoadingType === 'publish'" :disabled="!client.connected" @click="doPublish(publish.payload, connection.pubTopic)">
 							发布(Publish)
 						</el-button>
 					</el-col>
@@ -176,113 +157,104 @@
 
 		<el-card shadow="hover">
 			<h1>
-				<el-button @click="clsmsg" type="Success" size="default" :icon="Delete" title="点击清空历史记录">接收(Receive)</el-button>
-				<el-tag size="default" title="接收次数">收 {{ recvnum }}</el-tag>
-				<el-tag size="default" :title="dht_tm">{{ dht_wsd }}</el-tag>
-				<el-tag size="default" title="设备已工作时长">{{ parseInt(runSeconds) }} 秒</el-tag>
+				<el-button @click="clsmsg" type="success" :icon="Delete" title="点击清空历史记录">接收(Receive)</el-button>
+				<el-tag title="接收次数">收 {{ recvnum }}</el-tag>
+				<el-tag :title="dht_tm">{{ dht_wsd }}</el-tag>
+				<el-tag title="设备已工作时长">{{ parseInt(runSeconds) }} 秒</el-tag>
 				<el-button
 					type="success"
 					title="关闭一路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-if="connection.ch1_Status"
 					icon="ele-Check"
-					size="default"
 					id="ch1"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 01 00')"
 					>关闭</el-button
 				>
 				<el-button
 					type="warning"
 					title="打开一路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-else="!connection.ch1_Status"
 					icon="ele-CloseBold"
-					size="default"
 					id="ch1"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 01 01')"
 					>打开</el-button
 				>
 				<el-button
 					type="success"
 					title="关闭二路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-if="connection.ch2_Status"
 					icon="ele-Check"
-					size="default"
 					id="ch2"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 02 00')"
 					>关闭</el-button
 				>
 				<el-button
 					type="warning"
 					title="打开二路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-else="!connection.ch2_Status"
 					icon="ele-CloseBold"
-					size="default"
 					id="ch2"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 02 01')"
 					>打开</el-button
 				>
 				<el-button
 					type="success"
 					title="关闭三路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-if="connection.ch3_Status"
 					icon="ele-Check"
-					size="default"
 					id="ch3"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 03 00')"
 					>关闭</el-button
 				>
 				<el-button
 					type="warning"
 					title="打开三路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-else="!connection.ch3_Status"
 					icon="ele-CloseBold"
-					size="default"
 					id="ch3"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 03 01')"
 					>打开</el-button
 				>
 				<el-button
 					type="success"
 					title="关闭四路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-if="connection.ch4_Status"
 					icon="ele-Check"
-					size="default"
 					id="ch4"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 04 00')"
 					>关闭</el-button
 				>
 				<el-button
 					type="warning"
 					title="打开四路"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-else="!connection.ch4_Status"
 					icon="ele-CloseBold"
-					size="default"
 					id="ch4"
-					v-preventReClick="2000"
+					v-reclick="2000"
 					@click="switchLight('55 AA AA AA AA 81 04 01')"
 					>打开</el-button
 				>
 				<el-button
 					type="danger"
 					title="四路全部关闭"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-if="connection.all_Status"
 					icon="ele-SwitchButton"
-					size="default"
 					id="ch5"
 					@click="switchLight('55 AA AA AA AA 81 A4 00')"
 					>全关</el-button
@@ -290,16 +262,15 @@
 				<el-button
 					type="success"
 					title="四路全部打开"
-					:disabled="!connection.onlineStatus | !client.connected"
+					:disabled="!connection.onlineStatus || !client.connected"
 					v-else="!connection.all_Status"
 					icon="ele-Switch"
-					size="default"
 					id="ch5"
 					@click="switchLight('55 AA AA AA AA 81 A4 01')"
 					>全开</el-button
 				>
 
-				<el-alert v-if="!client.connected || !connection.onlineStatus" title="网络服务断开或设备离线!" center type="warning" effect="light" />
+				<el-alert v-if="!client.connected || !connection.onlineStatus" title="网络服务断开或设备离线!" center type="warning" effect="light" style="margin-top: 4px" />
 			</h1>
 			<!-- 绑定接收日志,只读 -->
 			<el-col :span="24">
@@ -347,7 +318,7 @@ const retryTimes = ref(0); //重连次数
  * ws -> 8083; wss -> 8084
  * By default, EMQX allows clients to connect without authentication.
  * https://docs.emqx.com/en/enterprise/v4.4/advanced/auth.html#anonymous-login
- 
+
  * for more options and details, please refer to https://github.com/mqttjs/MQTT.js#mqttclientstreambuilder-options
  */
 const connection = reactive({
@@ -748,20 +719,19 @@ const clsmsg = () => {
 <style lang="scss" scoped>
 .mqtt-box {
 	max-width: 100%;
-	padding: 4px;
-	margin: 10px auto 0 auto;
+	margin: 0 auto;
 }
 
 .header {
 	font-size: 24px;
 	font-weight: bold;
-	margin: -12px auto 8px auto;
+	margin: -6px auto 0px auto;
 }
 
 h1 {
 	font-size: 16px;
 	margin-top: 10px auto 20px auto;
-	padding: 5px 0px 5px 0;
+	padding: 6px 0px 6px 0;
 }
 
 .el-col {
@@ -772,7 +742,7 @@ h1 {
 	font-size: 13px;
 }
 .el-card {
-	margin-bottom: 12px;
+	margin-bottom: 6px;
 }
 .el-card__body {
 	padding: 24px;

+ 1 - 1
Web/src/views/system/codeGen/index.vue

@@ -53,7 +53,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 5 - 1
Web/src/views/system/database/index.vue

@@ -22,7 +22,11 @@
 					<el-button-group style="padding-left: 10px">
 						<el-button icon="ele-Plus" @click="openAddColumn"> 增加列 </el-button>
 						<el-button icon="ele-Plus" @click="openGenDialog"> 生成实体 </el-button>
-						<el-button icon="ele-Plus" @click="openGenSeedDataDialog"> 生成种子 </el-button>
+						<el-popover placement="bottom" title="温馨提示" :width="200" trigger="hover" content="如果是刚刚生成的实体,请重启服务后再生成种子">
+							<template #reference>
+								<el-button icon="ele-Plus" @click="openGenSeedDataDialog"> 生成种子 </el-button>
+							</template>
+						</el-popover>
 					</el-button-group>
 				</el-form-item>
 			</el-form>

+ 1 - 1
Web/src/views/system/dict/component/editDictData.vue

@@ -20,7 +20,7 @@
 						</el-form-item>
 					</el-col>
 					<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
-						<el-form-item label="名称" prop="name" :rules="[{ required: true, message: '名称不能为空', trigger: 'blur' }]">
+						<el-form-item label="名称" prop="name">
 							<el-input v-model="state.ruleForm.name" placeholder="名称" clearable />
 						</el-form-item>
 					</el-col>

+ 2 - 2
Web/src/views/system/dict/index.vue

@@ -59,7 +59,7 @@
 						v-model:page-size="state.tableDictTypeParams.pageSize"
 						:total="state.tableDictTypeParams.total"
 						:page-sizes="[10, 20, 50, 100]"
-						small
+						size="small"
 						background
 						@size-change="handleDictTypeSizeChange"
 						@current-change="handleDictTypeCurrentChange"
@@ -134,7 +134,7 @@
 						v-model:page-size="state.tableDictDataParams.pageSize"
 						:total="state.tableDictDataParams.total"
 						:page-sizes="[10, 20, 50, 100]"
-						small
+						size="small"
 						background
 						@size-change="handleDictDataSizeChange"
 						@current-change="handleDictDataCurrentChange"

+ 1 - 1
Web/src/views/system/file/index.vue

@@ -75,7 +75,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 2 - 2
Web/src/views/system/job/index.vue

@@ -206,7 +206,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"
@@ -249,7 +249,7 @@
 					v-model:page-size="state.tableParams2.pageSize"
 					:total="state.tableParams2.total"
 					:page-sizes="[10, 20, 50, 100]"
-					small
+					size="small"
 					background
 					@size-change="handleSizeChange2"
 					@current-change="handleCurrentChange2"

+ 1 - 1
Web/src/views/system/ldap/index.vue

@@ -55,7 +55,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100, 200, 500]"
-				small=""
+				size="small"
 				background=""
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/log/difflog/index.vue

@@ -38,7 +38,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/log/exlog/index.vue

@@ -72,7 +72,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/log/oplog/index.vue

@@ -72,7 +72,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/log/vislog/index.vue

@@ -47,7 +47,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/notice/index.vue

@@ -58,7 +58,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/onlineUser/index.vue

@@ -38,7 +38,7 @@
 					v-model:page-size="state.tableParams.pageSize"
 					:total="state.tableParams.total"
 					:page-sizes="[10, 20, 50, 100]"
-					small
+					size="small"
 					background
 					@size-change="handleSizeChange"
 					@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/openAccess/index.vue

@@ -43,7 +43,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/plugin/index.vue

@@ -46,7 +46,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/print/index.vue

@@ -46,7 +46,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/region/index.vue

@@ -46,7 +46,7 @@
 						v-model:page-size="state.tableParams.pageSize"
 						:total="state.tableParams.total"
 						:page-sizes="[10, 20, 50, 100]"
-						small
+						size="small"
 						background
 						@size-change="handleSizeChange"
 						@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/role/index.vue

@@ -59,7 +59,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/tenant/index.vue

@@ -99,7 +99,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"

+ 1 - 1
Web/src/views/system/user/index.vue

@@ -96,7 +96,7 @@
 						v-model:page-size="state.tableParams.pageSize"
 						:total="state.tableParams.total"
 						:page-sizes="[10, 20, 50, 100]"
-						small
+						size="small"
 						background
 						@size-change="handleSizeChange"
 						@current-change="handleCurrentChange"

+ 261 - 0
Web/src/views/system/weChatPay/index.vue

@@ -0,0 +1,261 @@
+<template>
+	<div class="weChatPay-container">
+		<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
+			<el-form :model="state.queryParams" ref="queryForm" :inline="true">
+				<el-form-item label="订单号">
+					<el-input v-model="state.queryParams.searchKey" clearable="" placeholder="请输入订单号" />
+				</el-form-item>
+				<el-form-item label="创建时间">
+					<el-date-picker placeholder="请选择创建时间" value-format="YYYY/MM/DD" type="daterange" v-model="state.queryParams.createTimeRange" />
+				</el-form-item>
+				<el-form-item>
+					<el-button-group>
+						<el-button type="primary" icon="ele-Search" @click="handleQuery"> 查询 </el-button>
+						<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
+					</el-button-group>
+				</el-form-item>
+				<el-form-item>
+					<el-button type="primary" icon="ele-Plus" @click="openAddDialog">新增模拟数据</el-button>
+				</el-form-item>
+			</el-form>
+		</el-card>
+
+		<el-card class="full-table" shadow="hover" style="margin-top: 5px">
+			<el-table :data="state.tableData" style="width: 100%" v-loading="state.loading" border="">
+				<el-table-column type="index" label="序号" width="55" align="center" />
+				<el-table-column prop="outTradeNumber" label="商户订单号" width="180"></el-table-column>
+				<el-table-column prop="transactionId" label="支付订单号" width="220"></el-table-column>
+				<el-table-column prop="description" label="描述" width="180"></el-table-column>
+				<el-table-column prop="total" :formatter="amountFormatter" label="金额" width="70"></el-table-column>
+				<el-table-column prop="tradeState" label="状态" width="70">
+					<template #default="scope">
+						<el-tag v-if="scope.row.tradeState == 'SUCCESS'" type="success"> 完成 </el-tag>
+						<el-tag v-else-if="scope.row.tradeState == 'REFUND'" type="danger"> 退款 </el-tag>
+						<el-tag v-else type="info"> 未完成 </el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="attachment" label="附加信息" width="180"></el-table-column>
+				<el-table-column prop="tags" label="业务类型" width="90"></el-table-column>
+				<el-table-column prop="createTime" label="创建时间" width="150"></el-table-column>
+				<el-table-column prop="successTime" label="完成时间" width="150"></el-table-column>
+				<el-table-column prop="businessId" label="业务ID" width="130"></el-table-column>
+				<el-table-column label="操作" align="center" fixed="right">
+					<template #default="scope">
+						<el-button
+							size="small"
+							text=""
+							type="primary"
+							v-if="scope.row.qrcodeContent != null && scope.row.qrcodeContent != '' && (scope.row.tradeState === '' || !scope.row.tradeState)"
+							@click="openQrDialog(scope.row.qrcodeContent)"
+							>付款二维码</el-button
+						>
+						<el-button size="small" text="" type="primary" v-if="scope.row.tradeState === 'REFUND'" @click="openRefundDialog(scope.row.transactionId)">查看退款</el-button>
+						<el-button size="small" text="" type="primary" v-if="scope.row.tradeState === 'SUCCESS'" @click="doRefund(scope.row)">全额退款</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<el-pagination
+				v-model:currentPage="state.tableParams.page"
+				v-model:page-size="state.tableParams.pageSize"
+				:total="state.tableParams.total"
+				:page-sizes="[10, 20, 50, 100]"
+				size="small"
+				background
+				@size-change="handleSizeChange"
+				@current-change="handleCurrentChange"
+				layout="total, sizes, prev, pager, next, jumper"
+			/>
+		</el-card>
+
+		<el-dialog v-model="showAddDialog" title="新增模拟数据">
+			<el-form>
+				<el-form-item label="商品">
+					<el-input v-model="addData.description" placeholder="必填" clearable />
+				</el-form-item>
+				<el-form-item label="金额(分)">
+					<el-input v-model="addData.total" placeholder="必填,填数字,单位是分" clearable />
+				</el-form-item>
+				<el-form-item label="附加信息">
+					<el-input v-model="addData.attachment" clearable />
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="closeAddDialog">取 消</el-button>
+					<el-button type="primary" @click="saveData">确 定</el-button>
+				</span>
+			</template>
+		</el-dialog>
+		<el-dialog title="付款二维码" v-model="showQrDialog">
+			<div ref="qrDiv"></div>
+		</el-dialog>
+
+		<el-dialog title="退款信息" v-model="showRefundDialog">
+			<el-table :data="subTableData" style="width: 100%" tooltip-effect="light" row-key="id" border="">
+				<el-table-column type="index" label="序号" width="55" align="center" />
+				<el-table-column prop="outRefundNumber" label="商户退款号" width="180"></el-table-column>
+				<el-table-column prop="transactionId" label="支付订单号" width="220"></el-table-column>
+				<el-table-column prop="refund" label="金额(分)" width="70"></el-table-column>
+				<el-table-column prop="reason" label="退款原因" width="180"></el-table-column>
+				<el-table-column prop="tradeState" label="状态" width="70">
+					<template #default="scope">
+						<el-tag v-if="scope.row.tradeState == 'SUCCESS'" type="success"> 完成 </el-tag>
+						<el-tag v-else-if="scope.row.tradeState == 'REFUND'" type="danger"> 退款 </el-tag>
+						<el-tag v-else type="info"> 未完成 </el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="remark" label="备注" width="180"></el-table-column>
+				<el-table-column prop="createTime" label="创建时间" width="150"></el-table-column>
+				<el-table-column prop="successTime" label="完成时间" width="150"></el-table-column>
+			</el-table>
+		</el-dialog>
+	</div>
+</template>
+
+<script setup lang="ts" name="weChatPay">
+import { ref, nextTick, onMounted, reactive } from 'vue';
+import { ElMessageBox, ElMessage } from 'element-plus';
+import QRCode from 'qrcodejs2-fixes';
+import { pagePayList, createPay, getRefundListByID, refundDomestic } from '/@/api/system/weChatPay';
+
+const qrDiv = ref<HTMLElement | null>(null);
+const showAddDialog = ref(false);
+const showQrDialog = ref(false);
+const showRefundDialog = ref(false);
+
+const subTableData = ref<any>([]);
+const addData = ref<any>({});
+
+const state = reactive({
+	loading: false,
+	tableData: [] as any,
+	queryParams: {
+		searchKey: undefined,
+		createTimeRange: undefined,
+	},
+	tableParams: {
+		page: 1,
+		pageSize: 10,
+		total: 0 as any,
+	},
+	editTenantTitle: '',
+});
+
+// 页面初始化
+onMounted(async () => {
+	handleQuery();
+});
+
+// 查询操作
+const handleQuery = async () => {
+	state.loading = true;
+	let params = Object.assign(state.queryParams, state.tableParams);
+	var res = await pagePayList(params);
+	let tmpRows = res.data.result?.items ?? [];
+	state.tableData.value = tmpRows;
+	state.tableParams.total = res.data.result?.total;
+	state.loading = false;
+};
+
+// 重置操作
+const resetQuery = () => {
+	state.queryParams.searchKey = undefined;
+	state.queryParams.createTimeRange = undefined;
+	handleQuery();
+};
+
+// 退款
+const doRefund = async (orderInfo: any) => {
+	ElMessageBox.prompt(`确定进行退款:${orderInfo.total / 100}元?请输入退款理由`, '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+	})
+		.then(async ({ value }) => {
+			let resp = await refundDomestic({
+				tradeId: orderInfo.outTradeNumber,
+				reason: value,
+				refund: orderInfo.total,
+				total: orderInfo.total,
+			});
+			if (resp.data.code == 200) {
+				ElMessage.success(`【${value}】退款申请成功`);
+			} else {
+				ElMessage.error('操作失败:' + resp.data.message);
+			}
+		})
+		.catch(() => {
+			ElMessage.error('取消操作');
+		});
+};
+
+const amountFormatter = (row: any, column: any, cellValue: number, index: number) => {
+	return (cellValue / 100).toFixed(2);
+};
+
+// 打开新增页面
+const openAddDialog = () => {
+	addData.value = {
+		description: null,
+		total: null,
+		attachment: null,
+	};
+	showAddDialog.value = true;
+};
+
+// 关闭新增页面
+const closeAddDialog = () => {
+	showAddDialog.value = false;
+};
+
+// 打开扫码页面
+const openQrDialog = (code: string) => {
+	showQrDialog.value = true;
+	nextTick(() => {
+		(<HTMLElement>qrDiv.value).innerHTML = '';
+		new QRCode(qrDiv.value, {
+			text: code,
+			width: 260,
+			height: 260,
+			colorDark: '#000000',
+			colorLight: '#ffffff',
+		});
+	});
+};
+
+// 打开退款页面
+const openRefundDialog = async (code: string) => {
+	var res = await getRefundListByID(code);
+	if (res.data.code === 200) {
+		let tmpRows = res.data.result ?? [];
+		subTableData.value = tmpRows;
+		showRefundDialog.value = true;
+	} else {
+		ElMessage.error('获取退款列表失败,' + res.data.message);
+	}
+};
+
+// 保存数据
+const saveData = async () => {
+	var res = await createPay(addData.value);
+	if (res.data.code === 200) {
+		closeAddDialog();
+		let code = res.data.result.qrcodeUrl;
+		openQrDialog(code);
+		handleQuery();
+	} else {
+		ElMessage.error('新建失败,' + res.data.message);
+	}
+};
+
+// 改变页面容量
+const handleSizeChange = (val: number) => {
+	state.tableParams.pageSize = val;
+	handleQuery();
+};
+
+// 改变页码序号
+const handleCurrentChange = (val: number) => {
+	state.tableParams.page = val;
+	handleQuery();
+};
+</script>

+ 1 - 1
Web/src/views/system/weChatUser/index.vue

@@ -60,7 +60,7 @@
 				v-model:page-size="state.tableParams.pageSize"
 				:total="state.tableParams.total"
 				:page-sizes="[10, 20, 50, 100]"
-				small
+				size="small"
 				background
 				@size-change="handleSizeChange"
 				@current-change="handleCurrentChange"