diff --git a/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj b/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj index 40a42f83..df59286c 100644 --- a/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj +++ b/Admin.NET/Admin.NET.Core/Admin.NET.Core.csproj @@ -17,27 +17,27 @@ - - - - + + + + - + - + - + @@ -45,7 +45,7 @@ - + @@ -56,9 +56,9 @@ - - - + + + diff --git a/Admin.NET/Admin.NET.Core/Entity/SysCodeGen.cs b/Admin.NET/Admin.NET.Core/Entity/SysCodeGen.cs index ba23d162..8ec86d27 100644 --- a/Admin.NET/Admin.NET.Core/Entity/SysCodeGen.cs +++ b/Admin.NET/Admin.NET.Core/Entity/SysCodeGen.cs @@ -1,125 +1,131 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core; - -/// -/// 代码生成表 -/// -[SugarTable(null, "代码生成表")] -[SysTable] -[SugarIndex("index_{table}_B", nameof(BusName), OrderByType.Asc)] -[SugarIndex("index_{table}_T", nameof(TableName), OrderByType.Asc)] -public partial class SysCodeGen : EntityBase -{ - /// - /// 作者姓名 - /// - [SugarColumn(ColumnDescription = "作者姓名", Length = 32)] - [MaxLength(32)] - public string? AuthorName { get; set; } - - /// - /// 是否移除表前缀 - /// - [SugarColumn(ColumnDescription = "是否移除表前缀", Length = 8)] - [MaxLength(8)] - public string? TablePrefix { get; set; } - - /// - /// 生成方式 - /// - [SugarColumn(ColumnDescription = "生成方式", Length = 32)] - [MaxLength(32)] - public string? GenerateType { get; set; } - - /// - /// 库定位器名 - /// - [SugarColumn(ColumnDescription = "库定位器名", Length = 64)] - [MaxLength(64)] - public string? ConfigId { get; set; } - - /// - /// 数据库名(保留字段) - /// - [SugarColumn(ColumnDescription = "数据库库名", Length = 64)] - [MaxLength(64)] - public string? DbName { get; set; } - - /// - /// 数据库类型 - /// - [SugarColumn(ColumnDescription = "数据库类型", Length = 64)] - [MaxLength(64)] - public string? DbType { get; set; } - - /// - /// 数据库链接 - /// - [SugarColumn(ColumnDescription = "数据库链接", Length = 256)] - [MaxLength(256)] - public string? ConnectionString { get; set; } - - /// - /// 数据库表名 - /// - [SugarColumn(ColumnDescription = "数据库表名", Length = 128)] - [MaxLength(128)] - public string? TableName { get; set; } - - /// - /// 命名空间 - /// - [SugarColumn(ColumnDescription = "命名空间", Length = 128)] - [MaxLength(128)] - public string? NameSpace { get; set; } - - /// - /// 业务名 - /// - [SugarColumn(ColumnDescription = "业务名", Length = 128)] - [MaxLength(128)] - public string? BusName { get; set; } - - /// - /// 是否生成菜单 - /// - [SugarColumn(ColumnDescription = "是否生成菜单")] - public bool GenerateMenu { get; set; } = true; - - /// - /// 菜单图标 - /// - [SugarColumn(ColumnDescription = "菜单图标", Length = 32)] - public string? MenuIcon { get; set; } = "ele-Menu"; - - /// - /// 菜单编码 - /// - [SugarColumn(ColumnDescription = "菜单编码")] - public long? MenuPid { get; set; } - - /// - /// 页面目录 - /// - [SugarColumn(ColumnDescription = "页面目录", Length = 32)] - public string? PagePath { get; set; } - - /// - /// 支持打印类型 - /// - [SugarColumn(ColumnDescription = "支持打印类型", Length = 32)] - [MaxLength(32)] - public string? PrintType { get; set; } - - /// - /// 打印模版名称 - /// - [SugarColumn(ColumnDescription = "打印模版名称", Length = 32)] - [MaxLength(32)] - public string? PrintName { get; set; } +// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 +// +// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 +// +// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + +namespace Admin.NET.Core; + +/// +/// 代码生成表 +/// +[SugarTable(null, "代码生成表")] +[SysTable] +[SugarIndex("index_{table}_B", nameof(BusName), OrderByType.Asc)] +[SugarIndex("index_{table}_T", nameof(TableName), OrderByType.Asc)] +public partial class SysCodeGen : EntityBase +{ + /// + /// 作者姓名 + /// + [SugarColumn(ColumnDescription = "作者姓名", Length = 32)] + [MaxLength(32)] + public string? AuthorName { get; set; } + + /// + /// 是否移除表前缀 + /// + [SugarColumn(ColumnDescription = "是否移除表前缀", Length = 8)] + [MaxLength(8)] + public string? TablePrefix { get; set; } + + /// + /// 生成方式 + /// + [SugarColumn(ColumnDescription = "生成方式", Length = 32)] + [MaxLength(32)] + public string? GenerateType { get; set; } + + /// + /// 库定位器名 + /// + [SugarColumn(ColumnDescription = "库定位器名", Length = 64)] + [MaxLength(64)] + public string? ConfigId { get; set; } + + /// + /// 数据库名(保留字段) + /// + [SugarColumn(ColumnDescription = "数据库库名", Length = 64)] + [MaxLength(64)] + public string? DbName { get; set; } + + /// + /// 数据库类型 + /// + [SugarColumn(ColumnDescription = "数据库类型", Length = 64)] + [MaxLength(64)] + public string? DbType { get; set; } + + /// + /// 数据库链接 + /// + [SugarColumn(ColumnDescription = "数据库链接", Length = 256)] + [MaxLength(256)] + public string? ConnectionString { get; set; } + + /// + /// 数据库表名 + /// + [SugarColumn(ColumnDescription = "数据库表名", Length = 128)] + [MaxLength(128)] + public string? TableName { get; set; } + + /// + /// 命名空间 + /// + [SugarColumn(ColumnDescription = "命名空间", Length = 128)] + [MaxLength(128)] + public string? NameSpace { get; set; } + + /// + /// 业务名 + /// + [SugarColumn(ColumnDescription = "业务名", Length = 128)] + [MaxLength(128)] + public string? BusName { get; set; } + + /// + /// 是否生成菜单 + /// + [SugarColumn(ColumnDescription = "是否生成菜单")] + public bool GenerateMenu { get; set; } = true; + + /// + /// 菜单图标 + /// + [SugarColumn(ColumnDescription = "菜单图标", Length = 32)] + public string? MenuIcon { get; set; } = "ele-Menu"; + + /// + /// 菜单编码 + /// + [SugarColumn(ColumnDescription = "菜单编码")] + public long? MenuPid { get; set; } + + /// + /// 页面目录 + /// + [SugarColumn(ColumnDescription = "页面目录", Length = 32)] + public string? PagePath { get; set; } + + /// + /// 支持打印类型 + /// + [SugarColumn(ColumnDescription = "支持打印类型", Length = 32)] + [MaxLength(32)] + public string? PrintType { get; set; } + + /// + /// 打印模版名称 + /// + [SugarColumn(ColumnDescription = "打印模版名称", Length = 32)] + [MaxLength(32)] + public string? PrintName { get; set; } + + /// + /// 是否使用 Api Service + /// + [SugarColumn(ColumnDescription = "是否使用 Api Service")] + public bool IsApiService { get; set; } = false; } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/SeedData/SysBaseApiSeedData.cs b/Admin.NET/Admin.NET.Core/SeedData/SysBaseApiSeedData.cs index 24055450..0f4b7152 100644 --- a/Admin.NET/Admin.NET.Core/SeedData/SysBaseApiSeedData.cs +++ b/Admin.NET/Admin.NET.Core/SeedData/SysBaseApiSeedData.cs @@ -19,33 +19,34 @@ public class SysBaseApiSeedData : ISqlSugarEntitySeedData { return new[] { - new SysBaseApi { Id = 1300000000001, Route = "sysAuth/login" }, - new SysBaseApi { Id = 1300000000002, Route = "sysAuth/unLockScreen" }, - new SysBaseApi { Id = 1300000000003, Route = "sysAuth/userInfo" }, - new SysBaseApi { Id = 1300000000004, Route = "sysAuth/refreshToken" }, - new SysBaseApi { Id = 1300000000005, Route = "sysAuth/loginConfig" }, - new SysBaseApi { Id = 1300000000006, Route = "sysAuth/watermarkConfig" }, - new SysBaseApi { Id = 1300000000007, Route = "sysAuth/captcha" }, - new SysBaseApi { Id = 1300000000008, Route = "sysMenu/loginMenuTree" }, - new SysBaseApi { Id = 1300000000009, Route = "sysOAuth/signIn" }, - new SysBaseApi { Id = 1300000000010, Route = "sysOAuth/signInCallback" }, - new SysBaseApi { Id = 1300000000011, Route = "sysOnlineUser/page" }, - new SysBaseApi { Id = 1300000000012, Route = "sysOrg/list" }, - new SysBaseApi { Id = 1300000000013, Route = "sysPos/list" }, - new SysBaseApi { Id = 1300000000014, Route = "sysRole/page" }, - new SysBaseApi { Id = 1300000000015, Route = "sysRole/list" }, - new SysBaseApi { Id = 1300000000016, Route = "sysFile/uploadAvatar" }, - new SysBaseApi { Id = 1300000000017, Route = "sysFile/uploadSignature" }, - new SysBaseApi { Id = 1300000000018, Route = "sysUser/baseInfo" }, - new SysBaseApi { Id = 1300000000019, Route = "sysUser/changePwd" }, - new SysBaseApi { Id = 1300000000020, Route = "sysNotice/page" }, - new SysBaseApi { Id = 1300000000021, Route = "sysNotice/add" }, - new SysBaseApi { Id = 1300000000022, Route = "sysNotice/update" }, - new SysBaseApi { Id = 1300000000023, Route = "sysNotice/delete" }, - new SysBaseApi { Id = 1300000000024, Route = "sysNotice/public" }, - new SysBaseApi { Id = 1300000000025, Route = "sysNotice/setRead" }, - new SysBaseApi { Id = 1300000000026, Route = "sysNotice/pageReceived" }, - new SysBaseApi { Id = 1300000000027, Route = "sysNotice/unReadList" }, + new SysBaseApi { Id = 1300000000010, Route = "sysAuth/login" }, + new SysBaseApi { Id = 1300000000020, Route = "sysAuth/unLockScreen" }, + new SysBaseApi { Id = 1300000000030, Route = "sysAuth/userInfo" }, + new SysBaseApi { Id = 1300000000040, Route = "sysAuth/refreshToken" }, + new SysBaseApi { Id = 1300000000050, Route = "sysAuth/loginConfig" }, + new SysBaseApi { Id = 1300000000060, Route = "sysAuth/watermarkConfig" }, + new SysBaseApi { Id = 1300000000070, Route = "sysAuth/captcha" }, + new SysBaseApi { Id = 1300000000080, Route = "sysAuth/logout" }, + new SysBaseApi { Id = 1300000000090, Route = "sysMenu/loginMenuTree" }, + new SysBaseApi { Id = 1300000000100, Route = "sysOAuth/signIn" }, + new SysBaseApi { Id = 1300000000110, Route = "sysOAuth/signInCallback" }, + new SysBaseApi { Id = 1300000000120, Route = "sysOnlineUser/page" }, + new SysBaseApi { Id = 1300000000130, Route = "sysOrg/list" }, + new SysBaseApi { Id = 1300000000140, Route = "sysPos/list" }, + new SysBaseApi { Id = 1300000000150, Route = "sysRole/page" }, + new SysBaseApi { Id = 1300000000160, Route = "sysRole/list" }, + new SysBaseApi { Id = 1300000000170, Route = "sysFile/uploadAvatar" }, + new SysBaseApi { Id = 1300000000180, Route = "sysFile/uploadSignature" }, + new SysBaseApi { Id = 1300000000190, Route = "sysUser/baseInfo" }, + new SysBaseApi { Id = 1300000000200, Route = "sysUser/changePwd" }, + new SysBaseApi { Id = 1300000000210, Route = "sysNotice/page" }, + new SysBaseApi { Id = 1300000000220, Route = "sysNotice/add" }, + new SysBaseApi { Id = 1300000000230, Route = "sysNotice/update" }, + new SysBaseApi { Id = 1300000000240, Route = "sysNotice/delete" }, + new SysBaseApi { Id = 1300000000250, Route = "sysNotice/public" }, + new SysBaseApi { Id = 1300000000260, Route = "sysNotice/setRead" }, + new SysBaseApi { Id = 1300000000270, Route = "sysNotice/pageReceived" }, + new SysBaseApi { Id = 1300000000280, Route = "sysNotice/unReadList" }, }; } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/Dto/SysLdapInput.cs b/Admin.NET/Admin.NET.Core/Service/Auth/Dto/SysLdapInput.cs index 009000b2..b4d45642 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/Dto/SysLdapInput.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/Dto/SysLdapInput.cs @@ -9,7 +9,7 @@ namespace Admin.NET.Core.Service; /// /// 系统域登录信息配置输入参数 /// -public class SysLdapInput : BasePageInput +public class PageSysLdapInput : BasePageInput { /// /// 关键字查询 diff --git a/Admin.NET/Admin.NET.Core/Service/Auth/SysLdapService.cs b/Admin.NET/Admin.NET.Core/Service/Auth/SysLdapService.cs index 2514891f..fd6679e8 100644 --- a/Admin.NET/Admin.NET.Core/Service/Auth/SysLdapService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Auth/SysLdapService.cs @@ -27,7 +27,7 @@ public class SysLdapService : IDynamicApiController, ITransient /// /// [DisplayName("获取系统域登录配置分页列表")] - public async Task> Page(SysLdapInput input) + public async Task> Page(PageSysLdapInput input) { return await _sysLdapRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u => u.Host.Contains(input.SearchKey.Trim())) diff --git a/Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs b/Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs index 4876809a..6ddead17 100644 --- a/Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Cache/SysCacheService.cs @@ -62,11 +62,11 @@ public class SysCacheService : IDynamicApiController, ISingleton return _cacheProvider.Cache.Set($"{_cacheOptions.Prefix}{key}", value, expire); } - /// - /// 获取缓存的剩余生存时间 - /// - /// - /// + /// + /// 获取缓存的剩余生存时间 + /// + /// + /// [NonAction] public TimeSpan GetExpire(string key) { diff --git a/Admin.NET/Admin.NET.Core/Service/CodeGen/CustomViewEngine.cs b/Admin.NET/Admin.NET.Core/Service/CodeGen/CustomViewEngine.cs index d202e728..a2f2449e 100644 --- a/Admin.NET/Admin.NET.Core/Service/CodeGen/CustomViewEngine.cs +++ b/Admin.NET/Admin.NET.Core/Service/CodeGen/CustomViewEngine.cs @@ -1,100 +1,102 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core.Service; - -public class CustomViewEngine : ViewEngineModel -{ - private readonly ISqlSugarClient _db; - - public CustomViewEngine() - { - } - - public CustomViewEngine(ISqlSugarClient db) - { - _db = db; - } - - /// - /// 库定位器 - /// - public string ConfigId { get; set; } = SqlSugarConst.MainConfigId; - - public string AuthorName { get; set; } - - public string BusName { get; set; } - - public string NameSpace { get; set; } - - public string ClassName { get; set; } - - public string ProjectLastName { get; set; } - - public string LowerClassName - { - get - { - return ClassName[..1].ToLower() + ClassName[1..]; // 首字母小写 - } - } - - public string PagePath { get; set; } = "main"; - - public bool IsJoinTable { get; set; } - - public bool IsUpload { get; set; } - - public string PrintType { get; set; } - - public string PrintName { get; set; } - - public List QueryWhetherList { get; set; } - - public List TableField { get; set; } - - private List ColumnList { get; set; } - - public string GetColumnNetType(object tbName, object colName) - { - if (tbName == null || colName == null) return null; - - var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == ConfigId); - ColumnList = GetColumnListByTableName(tbName.ToString()); - var col = ColumnList.Where(c => (config.DbSettings.EnableUnderLine - ? CodeGenUtil.CamelColumnName(c.ColumnName, Array.Empty()) - : c.ColumnName) == colName.ToString()).FirstOrDefault(); - return col.NetType; - } - - public List GetColumnListByTableName(string tableName) - { - // 多库代码生成切换库 - var provider = _db.AsTenant().GetConnectionScope(ConfigId != SqlSugarConst.MainConfigId ? ConfigId : SqlSugarConst.MainConfigId); - - // 获取实体类型属性 - var entityType = provider.DbMaintenance.GetTableInfoList().FirstOrDefault(u => u.Name == tableName); - - // 因为ConfigId的表通常也会用到主库的表来做连接,所以这里如果在ConfigId中找不到实体也尝试一下在主库中查找 - if (ConfigId == SqlSugarConst.MainConfigId && entityType == null) return null; - if (ConfigId != SqlSugarConst.MainConfigId) - { - provider = _db.AsTenant().GetConnectionScope(SqlSugarConst.MainConfigId); - entityType = provider.DbMaintenance.GetTableInfoList().FirstOrDefault(u => u.Name == tableName); - if (entityType == null) return null; - } - - // 按原始类型的顺序获取所有实体类型属性(不包含导航属性,会返回null) - return provider.DbMaintenance.GetColumnInfosByTableName(entityType.Name).Select(u => new ColumnOuput - { - ColumnName = u.DbColumnName, - ColumnKey = u.IsPrimarykey.ToString(), - DataType = u.DataType.ToString(), - NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), - ColumnComment = u.ColumnDescription - }).ToList(); - } +// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 +// +// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 +// +// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + +namespace Admin.NET.Core.Service; + +public class CustomViewEngine : ViewEngineModel +{ + private readonly ISqlSugarClient _db; + + public CustomViewEngine() + { + } + + public CustomViewEngine(ISqlSugarClient db) + { + _db = db; + } + + /// + /// 库定位器 + /// + public string ConfigId { get; set; } = SqlSugarConst.MainConfigId; + + public string AuthorName { get; set; } + + public string BusName { get; set; } + + public string NameSpace { get; set; } + + public string ClassName { get; set; } + + public string ProjectLastName { get; set; } + + public string LowerClassName + { + get + { + return ClassName[..1].ToLower() + ClassName[1..]; // 首字母小写 + } + } + + public string PagePath { get; set; } = "main"; + + public bool IsJoinTable { get; set; } + + public bool IsUpload { get; set; } + + public string PrintType { get; set; } + + public string PrintName { get; set; } + + public bool IsApiService { get; set; } + + public List QueryWhetherList { get; set; } + + public List TableField { get; set; } + + private List ColumnList { get; set; } + + public string GetColumnNetType(object tbName, object colName) + { + if (tbName == null || colName == null) return null; + + var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == ConfigId); + ColumnList = GetColumnListByTableName(tbName.ToString()); + var col = ColumnList.Where(c => (config.DbSettings.EnableUnderLine + ? CodeGenUtil.CamelColumnName(c.ColumnName, Array.Empty()) + : c.ColumnName) == colName.ToString()).FirstOrDefault(); + return col.NetType; + } + + public List GetColumnListByTableName(string tableName) + { + // 多库代码生成切换库 + var provider = _db.AsTenant().GetConnectionScope(ConfigId != SqlSugarConst.MainConfigId ? ConfigId : SqlSugarConst.MainConfigId); + + // 获取实体类型属性 + var entityType = provider.DbMaintenance.GetTableInfoList().FirstOrDefault(u => u.Name == tableName); + + // 因为ConfigId的表通常也会用到主库的表来做连接,所以这里如果在ConfigId中找不到实体也尝试一下在主库中查找 + if (ConfigId == SqlSugarConst.MainConfigId && entityType == null) return null; + if (ConfigId != SqlSugarConst.MainConfigId) + { + provider = _db.AsTenant().GetConnectionScope(SqlSugarConst.MainConfigId); + entityType = provider.DbMaintenance.GetTableInfoList().FirstOrDefault(u => u.Name == tableName); + if (entityType == null) return null; + } + + // 按原始类型的顺序获取所有实体类型属性(不包含导航属性,会返回null) + return provider.DbMaintenance.GetColumnInfosByTableName(entityType.Name).Select(u => new ColumnOuput + { + ColumnName = u.DbColumnName, + ColumnKey = u.IsPrimarykey.ToString(), + DataType = u.DataType.ToString(), + NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), + ColumnComment = u.ColumnDescription + }).ToList(); + } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenOutput.cs b/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenOutput.cs index aee96f67..3b90760d 100644 --- a/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenOutput.cs +++ b/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenOutput.cs @@ -1,83 +1,88 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -namespace Admin.NET.Core.Service; - -/// -/// 代码生成参数类 -/// -public class CodeGenOutput -{ - /// - /// 代码生成器Id - /// - public long Id { get; set; } - - /// - /// 作者姓名 - /// - public string AuthorName { get; set; } - - /// - /// 类名 - /// - public string ClassName { get; set; } - - /// - /// 是否移除表前缀 - /// - public string TablePrefix { get; set; } - - /// - /// 生成方式 - /// - public string GenerateType { get; set; } - - /// - /// 数据库表名 - /// - public string TableName { get; set; } - - /// - /// 包名 - /// - public string PackageName { get; set; } - - /// - /// 业务名(业务代码包名称) - /// - public string BusName { get; set; } - - /// - /// 功能名(数据库表名称) - /// - public string TableComment { get; set; } - - /// - /// 菜单应用分类(应用编码) - /// - public string MenuApplication { get; set; } - - /// - /// 是否生成菜单 - /// - public bool GenerateMenu { get; set; } - - /// - /// 菜单父级 - /// - public long? MenuPid { get; set; } - - /// - /// 支持打印类型 - /// - public string PrintType { get; set; } - - /// - /// 打印模版名称 - /// - public string PrintName { get; set; } +// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 +// +// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 +// +// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + +namespace Admin.NET.Core.Service; + +/// +/// 代码生成参数类 +/// +public class CodeGenOutput +{ + /// + /// 代码生成器Id + /// + public long Id { get; set; } + + /// + /// 作者姓名 + /// + public string AuthorName { get; set; } + + /// + /// 类名 + /// + public string ClassName { get; set; } + + /// + /// 是否移除表前缀 + /// + public string TablePrefix { get; set; } + + /// + /// 生成方式 + /// + public string GenerateType { get; set; } + + /// + /// 数据库表名 + /// + public string TableName { get; set; } + + /// + /// 包名 + /// + public string PackageName { get; set; } + + /// + /// 业务名(业务代码包名称) + /// + public string BusName { get; set; } + + /// + /// 功能名(数据库表名称) + /// + public string TableComment { get; set; } + + /// + /// 菜单应用分类(应用编码) + /// + public string MenuApplication { get; set; } + + /// + /// 是否生成菜单 + /// + public bool GenerateMenu { get; set; } + + /// + /// 菜单父级 + /// + public long? MenuPid { get; set; } + + /// + /// 支持打印类型 + /// + public string PrintType { get; set; } + + /// + /// 打印模版名称 + /// + public string PrintName { get; set; } + + /// + /// 是否使用 Api Service + /// + public bool IsApiService { get; set; } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenInput.cs b/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/PageCodeGenInput.cs similarity index 92% rename from Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenInput.cs rename to Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/PageCodeGenInput.cs index f44ff273..2e51e331 100644 --- a/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/CodeGenInput.cs +++ b/Admin.NET/Admin.NET.Core/Service/CodeGen/Dto/PageCodeGenInput.cs @@ -9,7 +9,7 @@ namespace Admin.NET.Core.Service; /// /// 代码生成参数类 /// -public class CodeGenInput : BasePageInput +public class PageCodeGenInput : BasePageInput { /// /// 作者姓名 @@ -100,9 +100,14 @@ public class CodeGenInput : BasePageInput /// 打印模版名称 /// public virtual string PrintName { get; set; } + + /// + /// 是否使用 Api Service + /// + public virtual bool IsApiService { get; set; } } -public class AddCodeGenInput : CodeGenInput +public class AddCodeGenInput : PageCodeGenInput { /// /// 数据库表名 @@ -157,6 +162,11 @@ public class AddCodeGenInput : CodeGenInput /// [Required(ErrorMessage = "是否生成菜单不能为空")] public override bool GenerateMenu { get; set; } + + /// + /// 是否使用 Api Service + /// + public override bool IsApiService { get; set; } } public class DeleteCodeGenInput @@ -168,7 +178,7 @@ public class DeleteCodeGenInput public long Id { get; set; } } -public class UpdateCodeGenInput : CodeGenInput +public class UpdateCodeGenInput : PageCodeGenInput { /// /// 代码生成器Id diff --git a/Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs b/Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs index 6f06463a..a6ab9946 100644 --- a/Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs +++ b/Admin.NET/Admin.NET.Core/Service/CodeGen/SysCodeGenService.cs @@ -1,811 +1,814 @@ -// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 -// -// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 -// -// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! - -using System.IO.Compression; - -namespace Admin.NET.Core.Service; - -/// -/// 系统代码生成器服务 🧩 -/// -[ApiDescriptionSettings(Order = 270)] -public class SysCodeGenService : IDynamicApiController, ITransient -{ - private readonly ISqlSugarClient _db; - - private readonly SysCodeGenConfigService _codeGenConfigService; - private readonly IViewEngine _viewEngine; - private readonly CodeGenOptions _codeGenOptions; - - public SysCodeGenService(ISqlSugarClient db, - SysCodeGenConfigService codeGenConfigService, - IViewEngine viewEngine, - IOptions codeGenOptions) - { - _db = db; - _codeGenConfigService = codeGenConfigService; - _viewEngine = viewEngine; - _codeGenOptions = codeGenOptions.Value; - } - - /// - /// 获取代码生成分页列表 🔖 - /// - /// - /// - [DisplayName("获取代码生成分页列表")] - public async Task> Page(CodeGenInput input) - { - return await _db.Queryable() - .WhereIF(!string.IsNullOrWhiteSpace(input.TableName), u => u.TableName.Contains(input.TableName.Trim())) - .WhereIF(!string.IsNullOrWhiteSpace(input.BusName), u => u.BusName.Contains(input.BusName.Trim())) - .ToPagedListAsync(input.Page, input.PageSize); - } - - /// - /// 增加代码生成 🔖 - /// - /// - /// - [ApiDescriptionSettings(Name = "Add"), HttpPost] - [DisplayName("增加代码生成")] - public async Task AddCodeGen(AddCodeGenInput input) - { - var isExist = await _db.Queryable().Where(u => u.TableName == input.TableName).AnyAsync(); - if (isExist) - throw Oops.Oh(ErrorCodeEnum.D1400); - - var codeGen = input.Adapt(); - var newCodeGen = await _db.Insertable(codeGen).ExecuteReturnEntityAsync(); - // 加入配置表中 - _codeGenConfigService.AddList(GetColumnList(input), newCodeGen); - } - - /// - /// 更新代码生成 🔖 - /// - /// - /// - [ApiDescriptionSettings(Name = "Update"), HttpPost] - [DisplayName("更新代码生成")] - public async Task UpdateCodeGen(UpdateCodeGenInput input) - { - var isExist = await _db.Queryable().AnyAsync(u => u.TableName == input.TableName && u.Id != input.Id); - if (isExist) - throw Oops.Oh(ErrorCodeEnum.D1400); - - await _db.Updateable(input.Adapt()).ExecuteCommandAsync(); - } - - /// - /// 删除代码生成 🔖 - /// - /// - /// - [ApiDescriptionSettings(Name = "Delete"), HttpPost] - [DisplayName("删除代码生成")] - public async Task DeleteCodeGen(List inputs) - { - if (inputs == null || inputs.Count < 1) return; - - var codeGenConfigTaskList = new List(); - inputs.ForEach(u => - { - _db.Deleteable().In(u.Id).ExecuteCommand(); - - // 删除配置表中 - codeGenConfigTaskList.Add(_codeGenConfigService.DeleteCodeGenConfig(u.Id)); - }); - await Task.WhenAll(codeGenConfigTaskList); - } - - /// - /// 获取代码生成详情 🔖 - /// - /// - /// - [DisplayName("获取代码生成详情")] - public async Task GetDetail([FromQuery] QueryCodeGenInput input) - { - return await _db.Queryable().SingleAsync(u => u.Id == input.Id); - } - - /// - /// 获取数据库库集合 🔖 - /// - /// - [DisplayName("获取数据库库集合")] - public async Task> GetDatabaseList() - { - var dbConfigs = App.GetOptions().ConnectionConfigs; - return await Task.FromResult(dbConfigs.Adapt>()); - } - - /// - /// 获取数据库表(实体)集合 🔖 - /// - /// - [DisplayName("获取数据库表(实体)集合")] - public async Task> GetTableList(string configId = SqlSugarConst.MainConfigId) - { - var provider = _db.AsTenant().GetConnectionScope(configId); - var dbTableInfos = provider.DbMaintenance.GetTableInfoList(false); // 不能走缓存,否则切库不起作用 - - var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => configId.Equals(u.ConfigId)); - - var dbTableNames = dbTableInfos.Select(u => u.Name.ToLower()).ToList(); - IEnumerable entityInfos = await GetEntityInfos(); - - var tableOutputList = new List(); - foreach (var item in entityInfos) - { - var table = dbTableInfos.FirstOrDefault(u => u.Name.ToLower() == (config.DbSettings.EnableUnderLine ? UtilMethods.ToUnderLine(item.DbTableName) : item.DbTableName).ToLower()); - if (table == null) continue; - tableOutputList.Add(new TableOutput - { - ConfigId = configId, - EntityName = item.EntityName, - TableName = table.Name, - TableComment = item.TableDescription - }); - } - return tableOutputList; - } - - /// - /// 根据表名获取列集合 🔖 - /// - /// - [DisplayName("根据表名获取列集合")] - public List GetColumnListByTableName([Required] string tableName, string configId = SqlSugarConst.MainConfigId) - { - // 切库---多库代码生成用 - var provider = _db.AsTenant().GetConnectionScope(configId); - - var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == configId); - // 获取实体类型属性 - var entityType = provider.DbMaintenance.GetTableInfoList(false).FirstOrDefault(u => u.Name == tableName); - if (entityType == null) return null; - var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)]; - // 按原始类型的顺序获取所有实体类型属性(不包含导航属性,会返回null) - return provider.DbMaintenance.GetColumnInfosByTableName(entityType.Name).Select(u => new ColumnOuput - { - ColumnName = config.DbSettings.EnableUnderLine ? CodeGenUtil.CamelColumnName(u.DbColumnName, entityBasePropertyNames) : u.DbColumnName, - ColumnKey = u.IsPrimarykey.ToString(), - DataType = u.DataType.ToString(), - NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), - ColumnComment = u.ColumnDescription - }).ToList(); - } - - /// - /// 获取数据表列(实体属性)集合 - /// - /// - private List GetColumnList([FromQuery] AddCodeGenInput input) - { - var entityType = GetEntityInfos().GetAwaiter().GetResult().FirstOrDefault(u => u.EntityName == input.TableName); - if (entityType == null) - return null; - var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == input.ConfigId); - var dbTableName = config.DbSettings.EnableUnderLine ? UtilMethods.ToUnderLine(entityType.DbTableName) : entityType.DbTableName; - - // 切库---多库代码生成用 - var provider = _db.AsTenant().GetConnectionScope(!string.IsNullOrEmpty(input.ConfigId) ? input.ConfigId : SqlSugarConst.MainConfigId); - - var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)]; - var columnInfos = provider.DbMaintenance.GetColumnInfosByTableName(dbTableName, false); - var result = columnInfos.Select(u => new ColumnOuput - { - // 转下划线后的列名需要再转回来(暂时不转) - //ColumnName = config.DbSettings.EnableUnderLine ? CodeGenUtil.CamelColumnName(u.DbColumnName, entityBasePropertyNames) : u.DbColumnName, - ColumnName = u.DbColumnName, - ColumnLength = u.Length, - IsPrimarykey = u.IsPrimarykey, - IsNullable = u.IsNullable, - ColumnKey = u.IsPrimarykey.ToString(), - NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), - DataType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), - ColumnComment = string.IsNullOrWhiteSpace(u.ColumnDescription) ? u.DbColumnName : u.ColumnDescription - }).ToList(); - - // 获取实体的属性信息,赋值给PropertyName属性(CodeFirst模式应以PropertyName为实际使用名称) - var entityProperties = entityType.Type.GetProperties(); - - for (int i = result.Count - 1; i >= 0; i--) - { - var columnOutput = result[i]; - // 先找自定义字段名的,如果找不到就再找自动生成字段名的(并且过滤掉没有SugarColumn的属性) - var propertyInfo = entityProperties.FirstOrDefault(u => (u.GetCustomAttribute()?.ColumnName ?? "").ToLower() == columnOutput.ColumnName.ToLower()) ?? - entityProperties.FirstOrDefault(u => u.GetCustomAttribute() != null && u.Name.ToLower() == (config.DbSettings.EnableUnderLine - ? CodeGenUtil.CamelColumnName(columnOutput.ColumnName, entityBasePropertyNames).ToLower() - : columnOutput.ColumnName.ToLower())); - if (propertyInfo != null) - { - columnOutput.PropertyName = propertyInfo.Name; - columnOutput.ColumnComment = propertyInfo.GetCustomAttribute().ColumnDescription; - } - else - { - result.RemoveAt(i); // 移除没有定义此属性的字段 - } - } - return result; - } - - /// - /// 获取库表信息 - /// - /// - private async Task> GetEntityInfos() - { - var entityInfos = new List(); - - var type = typeof(SugarTable); - var types = new List(); - if (_codeGenOptions.EntityAssemblyNames != null) - { - var assemblies = AppDomain.CurrentDomain.GetAssemblies(); - foreach (var assembly in assemblies) - { - var assemblyName = assembly.GetName().Name; - if (_codeGenOptions.EntityAssemblyNames.Contains(assemblyName) || _codeGenOptions.EntityAssemblyNames.Any(name => assemblyName.Contains(name))) - { - Assembly asm = Assembly.Load(assemblyName); - types.AddRange(asm.GetExportedTypes().ToList()); - } - } - } - bool IsMyAttribute(Attribute[] o) - { - foreach (Attribute a in o) - { - if (a.GetType() == type) - return true; - } - return false; - } - Type[] cosType = types.Where(o => - { - return IsMyAttribute(Attribute.GetCustomAttributes(o, true)); - } - ).ToArray(); - - foreach (var ct in cosType) - { - var sugarAttribute = ct.GetCustomAttributes(type, true)?.FirstOrDefault(); - - var des = ct.GetCustomAttributes(typeof(DescriptionAttribute), true); - var description = ""; - if (des.Length > 0) - { - description = ((DescriptionAttribute)des[0]).Description; - } - entityInfos.Add(new EntityInfo() - { - EntityName = ct.Name, - DbTableName = sugarAttribute == null ? ct.Name : ((SugarTable)sugarAttribute).TableName, - TableDescription = sugarAttribute == null ? description : ((SugarTable)sugarAttribute).TableDescription, - Type = ct - }); - } - return await Task.FromResult(entityInfos); - } - - /// - /// 获取程序保存位置 🔖 - /// - /// - [DisplayName("获取程序保存位置")] - public List GetApplicationNamespaces() - { - return _codeGenOptions.BackendApplicationNamespaces; - } - - /// - /// 代码生成到本地 🔖 - /// - /// - [DisplayName("代码生成到本地")] - public async Task RunLocal(SysCodeGen input) - { - if (string.IsNullOrEmpty(input.GenerateType)) - input.GenerateType = "200"; - - // 先删除该表已生成的菜单列表 - List targetPathList; - var zipPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "CodeGen", input.TableName); - if (input.GenerateType.StartsWith('1')) - { - targetPathList = GetZipPathList(input); - if (Directory.Exists(zipPath)) - Directory.Delete(zipPath, true); - } - else - targetPathList = GetTargetPathList(input); - - var tableFieldList = await _codeGenConfigService.GetList(new CodeGenConfig() { CodeGenId = input.Id }); // 字段集合 - var queryWhetherList = tableFieldList.Where(u => u.QueryWhether == YesNoEnum.Y.ToString()).ToList(); // 前端查询集合 - var joinTableList = tableFieldList.Where(u => u.EffectType == "Upload" || u.EffectType == "fk" || u.EffectType == "ApiTreeSelect").ToList(); // 需要连表查询的字段 - (string joinTableNames, string lowerJoinTableNames) = GetJoinTableStr(joinTableList); // 获取连表的实体名和别名 - - var data = new CustomViewEngine(_db) - { - ConfigId = input.ConfigId, - AuthorName = input.AuthorName, - BusName = input.BusName, - NameSpace = input.NameSpace, - ClassName = input.TableName, - PagePath = input.PagePath, - ProjectLastName = input.NameSpace.Split('.').Last(), - QueryWhetherList = queryWhetherList, - TableField = tableFieldList, - IsJoinTable = joinTableList.Count > 0, - IsUpload = joinTableList.Where(u => u.EffectType == "Upload").Any(), - PrintType = input.PrintType, - PrintName = input.PrintName, - }; - // 模板目录 - var templatePathList = GetTemplatePathList(input); - var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template"); - - for (var i = 0; i < templatePathList.Count; i++) - { - var templateFilePath = Path.Combine(templatePath, templatePathList[i]); - if (!File.Exists(templateFilePath)) continue; - var tContent = File.ReadAllText(templateFilePath); - var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder => - { - builder.AddAssemblyReferenceByName("System.Linq"); - builder.AddAssemblyReferenceByName("System.Collections"); - builder.AddUsing("System.Collections.Generic"); - builder.AddUsing("System.Linq"); - }); - var dirPath = new DirectoryInfo(targetPathList[i]).Parent.FullName; - if (!Directory.Exists(dirPath)) - Directory.CreateDirectory(dirPath); - File.WriteAllText(targetPathList[i], tResult, Encoding.UTF8); - } - if (input.GenerateMenu) - await AddMenu(input.TableName, input.BusName, input.MenuPid ?? 0, input.MenuIcon, input.PagePath, tableFieldList); - // 非ZIP压缩返回空 - if (!input.GenerateType.StartsWith('1')) - return null; - else - { - string downloadPath = zipPath + ".zip"; - // 判断是否存在同名称文件 - if (File.Exists(downloadPath)) - File.Delete(downloadPath); - ZipFile.CreateFromDirectory(zipPath, downloadPath); - return new { url = $"{App.HttpContext.Request.Scheme}://{App.HttpContext.Request.Host.Value}/CodeGen/{input.TableName}.zip" }; - } - } - - /// - /// 获取代码生成预览 🔖 - /// - /// - [DisplayName("获取代码生成预览")] - public async Task> Preview(SysCodeGen input) - { - var tableFieldList = await _codeGenConfigService.GetList(new CodeGenConfig() { CodeGenId = input.Id }); // 字段集合 - var queryWhetherList = tableFieldList.Where(u => u.QueryWhether == YesNoEnum.Y.ToString()).ToList(); // 前端查询集合 - var joinTableList = tableFieldList.Where(u => u.EffectType == "Upload" || u.EffectType == "fk" || u.EffectType == "ApiTreeSelect").ToList(); // 需要连表查询的字段 - (string joinTableNames, string lowerJoinTableNames) = GetJoinTableStr(joinTableList); // 获取连表的实体名和别名 - - var data = new CustomViewEngine(_db) - { - ConfigId = input.ConfigId, - AuthorName = input.AuthorName, - BusName = input.BusName, - NameSpace = input.NameSpace, - ClassName = input.TableName, - PagePath = input.PagePath, - ProjectLastName = input.NameSpace.Split('.').Last(), - QueryWhetherList = queryWhetherList, - TableField = tableFieldList, - IsJoinTable = joinTableList.Count > 0, - IsUpload = joinTableList.Where(u => u.EffectType == "Upload").Any(), - PrintType = input.PrintType, - PrintName = input.PrintName, - }; - - // 获取模板文件并替换 - var templatePathList = GetTemplatePathList(); - var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template"); - - var result = new Dictionary(); - for (var i = 0; i < templatePathList.Count; i++) - { - var templateFilePath = Path.Combine(templatePath, templatePathList[i]); - if (!File.Exists(templateFilePath)) continue; - var tContent = File.ReadAllText(templateFilePath); - var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder => - { - builder.AddAssemblyReferenceByName("System.Linq"); - builder.AddAssemblyReferenceByName("System.Collections"); - builder.AddUsing("System.Collections.Generic"); - builder.AddUsing("System.Linq"); - }); - result.Add(templatePathList[i]?.TrimEnd(".vm"), tResult); - } - - return result; - } - - /// - /// 获取连表的实体名和别名 - /// - /// - /// - private static (string, string) GetJoinTableStr(List configs) - { - var uploads = configs.Where(u => u.EffectType == "Upload").ToList(); - var fks = configs.Where(u => u.EffectType == "fk").ToList(); - string str = ""; // - string lowerStr = ""; // (o, i, c) - foreach (var item in uploads) - { - lowerStr += "sysFile_FK_" + item.LowerPropertyName + ","; - str += "SysFile,"; - } - foreach (var item in fks) - { - lowerStr += item.LowerFkEntityName + "_FK_" + item.LowerFkColumnName + ","; - str += item.FkEntityName + ","; - } - return (str.TrimEnd(','), lowerStr.TrimEnd(',')); - } - - /// - /// 增加菜单 - /// - /// - /// - /// - /// - /// - /// - /// - private async Task AddMenu(string className, string busName, long pid, string menuIcon, string pagePath, List tableFieldList) - { - var pPath = string.Empty; - // 若 pid=0 为顶级则创建菜单目录 - if (pid == 0) - { - // 目录 - var menuType0 = new SysMenu - { - Pid = 0, - Title = busName + "管理", - Type = MenuTypeEnum.Dir, - Icon = "robot", - Path = "/" + className.ToLower(), - Component = "Layout", - }; - // 若先前存在则删除本级和下级 - var menuList0 = await _db.Queryable().Where(u => u.Title == menuType0.Title && u.Type == menuType0.Type).ToListAsync(); - if (menuList0.Count > 0) - { - var listIds = menuList0.Select(u => u.Id).ToList(); - var childlistIds = new List(); - foreach (var item in listIds) - { - var childlist = await _db.Queryable().ToChildListAsync(u => u.Pid, item); - childlistIds.AddRange(childlist.Select(u => u.Id).ToList()); - } - listIds.AddRange(childlistIds); - await _db.Deleteable().Where(u => listIds.Contains(u.Id)).ExecuteCommandAsync(); - await _db.Deleteable().Where(u => listIds.Contains(u.MenuId)).ExecuteCommandAsync(); - } - pid = (await _db.Insertable(menuType0).ExecuteReturnEntityAsync()).Id; - } - else - { - var pMenu = await _db.Queryable().FirstAsync(u => u.Id == pid) ?? throw Oops.Oh(ErrorCodeEnum.D1505); - pPath = pMenu.Path; - } - - // 菜单 - var menuType = new SysMenu - { - Pid = pid, - Title = busName + "管理", - Name = className[..1].ToLower() + className[1..], - Type = MenuTypeEnum.Menu, - Icon = menuIcon, - Path = pPath + "/" + className.ToLower(), - Component = "/" + pagePath + "/" + className[..1].ToLower() + className[1..] + "/index", - }; - // 若先前存在则删除本级和下级 - var menuListCurrent = await _db.Queryable().Where(u => u.Title == menuType.Title && u.Type == menuType.Type).ToListAsync(); - if (menuListCurrent.Count > 0) - { - var listIds = menuListCurrent.Select(u => u.Id).ToList(); - var childListIds = new List(); - foreach (var item in listIds) - { - var childList = await _db.Queryable().ToChildListAsync(u => u.Pid, item); - childListIds.AddRange(childList.Select(u => u.Id).ToList()); - } - listIds.AddRange(childListIds); - await _db.Deleteable().Where(u => listIds.Contains(u.Id)).ExecuteCommandAsync(); - await _db.Deleteable().Where(u => listIds.Contains(u.MenuId)).ExecuteCommandAsync(); - } - - var menuPid = (await _db.Insertable(menuType).ExecuteReturnEntityAsync()).Id; - int menuOrder = 100; - // 按钮-page - var menuTypePage = new SysMenu - { - Pid = menuPid, - Title = "查询", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":page", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-detail - var menuTypeDetail = new SysMenu - { - Pid = menuPid, - Title = "详情", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":detail", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-add - var menuTypeAdd = new SysMenu - { - Pid = menuPid, - Title = "增加", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":add", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-delete - var menuTypeDelete = new SysMenu - { - Pid = menuPid, - Title = "删除", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":delete", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-update - var menuTypeUpdate = new SysMenu - { - Pid = menuPid, - Title = "编辑", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":update", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-print - var menuTypePrint = new SysMenu - { - Pid = menuPid, - Title = "打印", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":print", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-import - var menuTypeImport = new SysMenu - { - Pid = menuPid, - Title = "导入", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":import", - OrderNo = menuOrder - }; - menuOrder += 10; - - // 按钮-export - var menuTypeExport = new SysMenu - { - Pid = menuPid, - Title = "导出", - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":export", - OrderNo = menuOrder - }; - menuOrder += 10; - - var menuList = new List() { menuTypePage, menuTypeDetail, menuTypeAdd, menuTypeDelete, menuTypeUpdate, menuTypePrint, menuTypeImport, menuTypeExport }; - // 加入fk、Upload、ApiTreeSelect 等接口的权限 - // 在生成表格时,有些字段只是查询时显示,不需要填写(WhetherAddUpdate),所以这些字段没必要生成相应接口 - var fkTableList = tableFieldList.Where(u => u.EffectType == "fk" && (u.WhetherAddUpdate == "Y" || u.QueryWhether == "Y")).ToList(); - foreach (var @column in fkTableList) - { - var menuType1 = new SysMenu - { - Pid = menuPid, - Title = "外键" + @column.ColumnName, - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":" + column.FkEntityName + column.ColumnName + "Dropdown", - OrderNo = menuOrder - }; - menuOrder += 10; - menuList.Add(menuType1); - } - var treeSelectTableList = tableFieldList.Where(u => u.EffectType == "ApiTreeSelect").ToList(); - foreach (var @column in treeSelectTableList) - { - var menuType1 = new SysMenu - { - Pid = menuPid, - Title = "树型" + @column.ColumnName, - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":" + column.FkEntityName + "Tree", - OrderNo = menuOrder - }; - menuOrder += 10; - menuList.Add(menuType1); - } - var uploadTableList = tableFieldList.Where(u => u.EffectType == "Upload").ToList(); - foreach (var @column in uploadTableList) - { - var menuType1 = new SysMenu - { - Pid = menuPid, - Title = "上传" + @column.ColumnName, - Type = MenuTypeEnum.Btn, - Permission = className[..1].ToLower() + className[1..] + ":Upload" + column.ColumnName, - OrderNo = menuOrder - }; - menuOrder += 10; - menuList.Add(menuType1); - } - await _db.Insertable(menuList).ExecuteCommandAsync(); - } - - /// - /// 获取模板文件路径集合 - /// - /// - private static List GetTemplatePathList(SysCodeGen input) - { - if (input.GenerateType.Substring(1, 1).Contains('1')) - { - return new() { "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; - } - else if (input.GenerateType.Substring(1, 1).Contains('2')) - { - return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm" }; - } - else - { - return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; - } - } - - /// - /// 获取模板文件路径集合 - /// - /// - private static List GetTemplatePathList() => new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; - - /// - /// 设置生成文件路径 - /// - /// - /// - private List GetTargetPathList(SysCodeGen input) - { - //var backendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName, _codeGenOptions.BackendApplicationNamespace, "Service", input.TableName); - var backendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName, input.NameSpace, "Service", input.TableName); - var servicePath = Path.Combine(backendPath, input.TableName + "Service.cs"); - var inputPath = Path.Combine(backendPath, "Dto", input.TableName + "Input.cs"); - var outputPath = Path.Combine(backendPath, "Dto", input.TableName + "Output.cs"); - var viewPath = Path.Combine(backendPath, "Dto", input.TableName + "Dto.cs"); - var frontendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "views", input.PagePath); - var indexPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "index.vue");// - var formModalPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "component", "editDialog.vue"); - var apiJsPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "api", input.PagePath, input.TableName[..1].ToLower() + input.TableName[1..] + ".ts"); - - if (input.GenerateType.Substring(1, 1).Contains('1')) - { - // 生成到本项目(前端) - return new List() - { - indexPath, - formModalPath, - apiJsPath - }; - } - else if (input.GenerateType.Substring(1, 1).Contains('2')) - { - // 生成到本项目(后端) - return new List() - { - servicePath, - inputPath, - outputPath, - viewPath, - }; - } - else - { - // 前后端同时生成到本项目 - return new List() - { - servicePath, - inputPath, - outputPath, - viewPath, - indexPath, - formModalPath, - apiJsPath - }; - } - } - - /// - /// 设置生成文件路径 - /// - /// - /// - private List GetZipPathList(SysCodeGen input) - { - var zipPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "CodeGen", input.TableName); - - //var backendPath = Path.Combine(zipPath, _codeGenOptions.BackendApplicationNamespace, "Service", input.TableName); - var backendPath = Path.Combine(zipPath, input.NameSpace, "Service", input.TableName); - var servicePath = Path.Combine(backendPath, input.TableName + "Service.cs"); - var inputPath = Path.Combine(backendPath, "Dto", input.TableName + "Input.cs"); - var outputPath = Path.Combine(backendPath, "Dto", input.TableName + "Output.cs"); - var viewPath = Path.Combine(backendPath, "Dto", input.TableName + "Dto.cs"); - var frontendPath = Path.Combine(zipPath, _codeGenOptions.FrontRootPath, "src", "views", input.PagePath); - var indexPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "index.vue"); - var formModalPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "component", "editDialog.vue"); - var apiJsPath = Path.Combine(zipPath, _codeGenOptions.FrontRootPath, "src", "api", input.PagePath, input.TableName[..1].ToLower() + input.TableName[1..] + ".ts"); - if (input.GenerateType.StartsWith("11")) - { - return new List() - { - indexPath, - formModalPath, - apiJsPath - }; - } - else if (input.GenerateType.StartsWith("12")) - { - return new List() - { - servicePath, - inputPath, - outputPath, - viewPath - }; - } - else - { - return new List() - { - servicePath, - inputPath, - outputPath, - viewPath, - indexPath, - formModalPath, - apiJsPath - }; - } - } +// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 +// +// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 +// +// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + +using System.IO.Compression; + +namespace Admin.NET.Core.Service; + +/// +/// 系统代码生成器服务 🧩 +/// +[ApiDescriptionSettings(Order = 270)] +public class SysCodeGenService : IDynamicApiController, ITransient +{ + private readonly ISqlSugarClient _db; + + private readonly SysCodeGenConfigService _codeGenConfigService; + private readonly IViewEngine _viewEngine; + private readonly CodeGenOptions _codeGenOptions; + + public SysCodeGenService(ISqlSugarClient db, + SysCodeGenConfigService codeGenConfigService, + IViewEngine viewEngine, + IOptions codeGenOptions) + { + _db = db; + _codeGenConfigService = codeGenConfigService; + _viewEngine = viewEngine; + _codeGenOptions = codeGenOptions.Value; + } + + /// + /// 获取代码生成分页列表 🔖 + /// + /// + /// + [DisplayName("获取代码生成分页列表")] + public async Task> Page(PageCodeGenInput input) + { + return await _db.Queryable() + .WhereIF(!string.IsNullOrWhiteSpace(input.TableName), u => u.TableName.Contains(input.TableName.Trim())) + .WhereIF(!string.IsNullOrWhiteSpace(input.BusName), u => u.BusName.Contains(input.BusName.Trim())) + .OrderBy(u => u.Id, OrderByType.Desc) + .ToPagedListAsync(input.Page, input.PageSize); + } + + /// + /// 增加代码生成 🔖 + /// + /// + /// + [ApiDescriptionSettings(Name = "Add"), HttpPost] + [DisplayName("增加代码生成")] + public async Task AddCodeGen(AddCodeGenInput input) + { + var isExist = await _db.Queryable().Where(u => u.TableName == input.TableName).AnyAsync(); + if (isExist) + throw Oops.Oh(ErrorCodeEnum.D1400); + + var codeGen = input.Adapt(); + var newCodeGen = await _db.Insertable(codeGen).ExecuteReturnEntityAsync(); + // 加入配置表中 + _codeGenConfigService.AddList(GetColumnList(input), newCodeGen); + } + + /// + /// 更新代码生成 🔖 + /// + /// + /// + [ApiDescriptionSettings(Name = "Update"), HttpPost] + [DisplayName("更新代码生成")] + public async Task UpdateCodeGen(UpdateCodeGenInput input) + { + var isExist = await _db.Queryable().AnyAsync(u => u.TableName == input.TableName && u.Id != input.Id); + if (isExist) + throw Oops.Oh(ErrorCodeEnum.D1400); + + await _db.Updateable(input.Adapt()).ExecuteCommandAsync(); + } + + /// + /// 删除代码生成 🔖 + /// + /// + /// + [ApiDescriptionSettings(Name = "Delete"), HttpPost] + [DisplayName("删除代码生成")] + public async Task DeleteCodeGen(List inputs) + { + if (inputs == null || inputs.Count < 1) return; + + var codeGenConfigTaskList = new List(); + inputs.ForEach(u => + { + _db.Deleteable().In(u.Id).ExecuteCommand(); + + // 删除配置表中 + codeGenConfigTaskList.Add(_codeGenConfigService.DeleteCodeGenConfig(u.Id)); + }); + await Task.WhenAll(codeGenConfigTaskList); + } + + /// + /// 获取代码生成详情 🔖 + /// + /// + /// + [DisplayName("获取代码生成详情")] + public async Task GetDetail([FromQuery] QueryCodeGenInput input) + { + return await _db.Queryable().SingleAsync(u => u.Id == input.Id); + } + + /// + /// 获取数据库库集合 🔖 + /// + /// + [DisplayName("获取数据库库集合")] + public async Task> GetDatabaseList() + { + var dbConfigs = App.GetOptions().ConnectionConfigs; + return await Task.FromResult(dbConfigs.Adapt>()); + } + + /// + /// 获取数据库表(实体)集合 🔖 + /// + /// + [DisplayName("获取数据库表(实体)集合")] + public async Task> GetTableList(string configId = SqlSugarConst.MainConfigId) + { + var provider = _db.AsTenant().GetConnectionScope(configId); + var dbTableInfos = provider.DbMaintenance.GetTableInfoList(false); // 不能走缓存,否则切库不起作用 + + var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => configId.Equals(u.ConfigId)); + + var dbTableNames = dbTableInfos.Select(u => u.Name.ToLower()).ToList(); + IEnumerable entityInfos = await GetEntityInfos(); + + var tableOutputList = new List(); + foreach (var item in entityInfos) + { + var table = dbTableInfos.FirstOrDefault(u => u.Name.ToLower() == (config.DbSettings.EnableUnderLine ? UtilMethods.ToUnderLine(item.DbTableName) : item.DbTableName).ToLower()); + if (table == null) continue; + tableOutputList.Add(new TableOutput + { + ConfigId = configId, + EntityName = item.EntityName, + TableName = table.Name, + TableComment = item.TableDescription + }); + } + return tableOutputList; + } + + /// + /// 根据表名获取列集合 🔖 + /// + /// + [DisplayName("根据表名获取列集合")] + public List GetColumnListByTableName([Required] string tableName, string configId = SqlSugarConst.MainConfigId) + { + // 切库---多库代码生成用 + var provider = _db.AsTenant().GetConnectionScope(configId); + + var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == configId); + // 获取实体类型属性 + var entityType = provider.DbMaintenance.GetTableInfoList(false).FirstOrDefault(u => u.Name == tableName); + if (entityType == null) return null; + var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)]; + // 按原始类型的顺序获取所有实体类型属性(不包含导航属性,会返回null) + return provider.DbMaintenance.GetColumnInfosByTableName(entityType.Name).Select(u => new ColumnOuput + { + ColumnName = config.DbSettings.EnableUnderLine ? CodeGenUtil.CamelColumnName(u.DbColumnName, entityBasePropertyNames) : u.DbColumnName, + ColumnKey = u.IsPrimarykey.ToString(), + DataType = u.DataType.ToString(), + NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), + ColumnComment = u.ColumnDescription + }).ToList(); + } + + /// + /// 获取数据表列(实体属性)集合 + /// + /// + private List GetColumnList([FromQuery] AddCodeGenInput input) + { + var entityType = GetEntityInfos().GetAwaiter().GetResult().FirstOrDefault(u => u.EntityName == input.TableName); + if (entityType == null) + return null; + var config = App.GetOptions().ConnectionConfigs.FirstOrDefault(u => u.ConfigId.ToString() == input.ConfigId); + var dbTableName = config.DbSettings.EnableUnderLine ? UtilMethods.ToUnderLine(entityType.DbTableName) : entityType.DbTableName; + + // 切库---多库代码生成用 + var provider = _db.AsTenant().GetConnectionScope(!string.IsNullOrEmpty(input.ConfigId) ? input.ConfigId : SqlSugarConst.MainConfigId); + + var entityBasePropertyNames = _codeGenOptions.EntityBaseColumn[nameof(EntityTenant)]; + var columnInfos = provider.DbMaintenance.GetColumnInfosByTableName(dbTableName, false); + var result = columnInfos.Select(u => new ColumnOuput + { + // 转下划线后的列名需要再转回来(暂时不转) + //ColumnName = config.DbSettings.EnableUnderLine ? CodeGenUtil.CamelColumnName(u.DbColumnName, entityBasePropertyNames) : u.DbColumnName, + ColumnName = u.DbColumnName, + ColumnLength = u.Length, + IsPrimarykey = u.IsPrimarykey, + IsNullable = u.IsNullable, + ColumnKey = u.IsPrimarykey.ToString(), + NetType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), + DataType = CodeGenUtil.ConvertDataType(u, provider.CurrentConnectionConfig.DbType), + ColumnComment = string.IsNullOrWhiteSpace(u.ColumnDescription) ? u.DbColumnName : u.ColumnDescription + }).ToList(); + + // 获取实体的属性信息,赋值给PropertyName属性(CodeFirst模式应以PropertyName为实际使用名称) + var entityProperties = entityType.Type.GetProperties(); + + for (int i = result.Count - 1; i >= 0; i--) + { + var columnOutput = result[i]; + // 先找自定义字段名的,如果找不到就再找自动生成字段名的(并且过滤掉没有SugarColumn的属性) + var propertyInfo = entityProperties.FirstOrDefault(u => (u.GetCustomAttribute()?.ColumnName ?? "").ToLower() == columnOutput.ColumnName.ToLower()) ?? + entityProperties.FirstOrDefault(u => u.GetCustomAttribute() != null && u.Name.ToLower() == (config.DbSettings.EnableUnderLine + ? CodeGenUtil.CamelColumnName(columnOutput.ColumnName, entityBasePropertyNames).ToLower() + : columnOutput.ColumnName.ToLower())); + if (propertyInfo != null) + { + columnOutput.PropertyName = propertyInfo.Name; + columnOutput.ColumnComment = propertyInfo.GetCustomAttribute().ColumnDescription; + } + else + { + result.RemoveAt(i); // 移除没有定义此属性的字段 + } + } + return result; + } + + /// + /// 获取库表信息 + /// + /// + private async Task> GetEntityInfos() + { + var entityInfos = new List(); + + var type = typeof(SugarTable); + var types = new List(); + if (_codeGenOptions.EntityAssemblyNames != null) + { + var assemblies = AppDomain.CurrentDomain.GetAssemblies(); + foreach (var assembly in assemblies) + { + var assemblyName = assembly.GetName().Name; + if (_codeGenOptions.EntityAssemblyNames.Contains(assemblyName) || _codeGenOptions.EntityAssemblyNames.Any(name => assemblyName.Contains(name))) + { + Assembly asm = Assembly.Load(assemblyName); + types.AddRange(asm.GetExportedTypes().ToList()); + } + } + } + bool IsMyAttribute(Attribute[] o) + { + foreach (Attribute a in o) + { + if (a.GetType() == type) + return true; + } + return false; + } + Type[] cosType = types.Where(o => + { + return IsMyAttribute(Attribute.GetCustomAttributes(o, true)); + } + ).ToArray(); + + foreach (var ct in cosType) + { + var sugarAttribute = ct.GetCustomAttributes(type, true)?.FirstOrDefault(); + + var des = ct.GetCustomAttributes(typeof(DescriptionAttribute), true); + var description = ""; + if (des.Length > 0) + { + description = ((DescriptionAttribute)des[0]).Description; + } + entityInfos.Add(new EntityInfo() + { + EntityName = ct.Name, + DbTableName = sugarAttribute == null ? ct.Name : ((SugarTable)sugarAttribute).TableName, + TableDescription = sugarAttribute == null ? description : ((SugarTable)sugarAttribute).TableDescription, + Type = ct + }); + } + return await Task.FromResult(entityInfos); + } + + /// + /// 获取程序保存位置 🔖 + /// + /// + [DisplayName("获取程序保存位置")] + public List GetApplicationNamespaces() + { + return _codeGenOptions.BackendApplicationNamespaces; + } + + /// + /// 代码生成到本地 🔖 + /// + /// + [DisplayName("代码生成到本地")] + public async Task RunLocal(SysCodeGen input) + { + if (string.IsNullOrEmpty(input.GenerateType)) + input.GenerateType = "200"; + + // 先删除该表已生成的菜单列表 + List targetPathList; + var zipPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "CodeGen", input.TableName); + if (input.GenerateType.StartsWith('1')) + { + targetPathList = GetZipPathList(input); + if (Directory.Exists(zipPath)) + Directory.Delete(zipPath, true); + } + else + targetPathList = GetTargetPathList(input); + + var tableFieldList = await _codeGenConfigService.GetList(new CodeGenConfig() { CodeGenId = input.Id }); // 字段集合 + var queryWhetherList = tableFieldList.Where(u => u.QueryWhether == YesNoEnum.Y.ToString()).ToList(); // 前端查询集合 + var joinTableList = tableFieldList.Where(u => u.EffectType == "Upload" || u.EffectType == "fk" || u.EffectType == "ApiTreeSelect").ToList(); // 需要连表查询的字段 + (string joinTableNames, string lowerJoinTableNames) = GetJoinTableStr(joinTableList); // 获取连表的实体名和别名 + + var data = new CustomViewEngine(_db) + { + ConfigId = input.ConfigId, + AuthorName = input.AuthorName, + BusName = input.BusName, + NameSpace = input.NameSpace, + ClassName = input.TableName, + PagePath = input.PagePath, + ProjectLastName = input.NameSpace.Split('.').Last(), + QueryWhetherList = queryWhetherList, + TableField = tableFieldList, + IsJoinTable = joinTableList.Count > 0, + IsUpload = joinTableList.Where(u => u.EffectType == "Upload").Any(), + PrintType = input.PrintType, + PrintName = input.PrintName, + IsApiService = input.IsApiService + }; + // 模板目录 + var templatePathList = GetTemplatePathList(input); + var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template"); + + for (var i = 0; i < templatePathList.Count; i++) + { + var templateFilePath = Path.Combine(templatePath, templatePathList[i]); + if (!File.Exists(templateFilePath)) continue; + var tContent = File.ReadAllText(templateFilePath); + var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder => + { + builder.AddAssemblyReferenceByName("System.Linq"); + builder.AddAssemblyReferenceByName("System.Collections"); + builder.AddUsing("System.Collections.Generic"); + builder.AddUsing("System.Linq"); + }); + var dirPath = new DirectoryInfo(targetPathList[i]).Parent.FullName; + if (!Directory.Exists(dirPath)) + Directory.CreateDirectory(dirPath); + File.WriteAllText(targetPathList[i], tResult, Encoding.UTF8); + } + if (input.GenerateMenu) + await AddMenu(input.TableName, input.BusName, input.MenuPid ?? 0, input.MenuIcon, input.PagePath, tableFieldList); + // 非ZIP压缩返回空 + if (!input.GenerateType.StartsWith('1')) + return null; + else + { + string downloadPath = zipPath + ".zip"; + // 判断是否存在同名称文件 + if (File.Exists(downloadPath)) + File.Delete(downloadPath); + ZipFile.CreateFromDirectory(zipPath, downloadPath); + return new { url = $"{App.HttpContext.Request.Scheme}://{App.HttpContext.Request.Host.Value}/CodeGen/{input.TableName}.zip" }; + } + } + + /// + /// 获取代码生成预览 🔖 + /// + /// + [DisplayName("获取代码生成预览")] + public async Task> Preview(SysCodeGen input) + { + var tableFieldList = await _codeGenConfigService.GetList(new CodeGenConfig() { CodeGenId = input.Id }); // 字段集合 + var queryWhetherList = tableFieldList.Where(u => u.QueryWhether == YesNoEnum.Y.ToString()).ToList(); // 前端查询集合 + var joinTableList = tableFieldList.Where(u => u.EffectType == "Upload" || u.EffectType == "fk" || u.EffectType == "ApiTreeSelect").ToList(); // 需要连表查询的字段 + (string joinTableNames, string lowerJoinTableNames) = GetJoinTableStr(joinTableList); // 获取连表的实体名和别名 + + var data = new CustomViewEngine(_db) + { + ConfigId = input.ConfigId, + AuthorName = input.AuthorName, + BusName = input.BusName, + NameSpace = input.NameSpace, + ClassName = input.TableName, + PagePath = input.PagePath, + ProjectLastName = input.NameSpace.Split('.').Last(), + QueryWhetherList = queryWhetherList, + TableField = tableFieldList, + IsJoinTable = joinTableList.Count > 0, + IsUpload = joinTableList.Where(u => u.EffectType == "Upload").Any(), + PrintType = input.PrintType, + PrintName = input.PrintName, + IsApiService = input.IsApiService + }; + + // 获取模板文件并替换 + var templatePathList = GetTemplatePathList(); + var templatePath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Template"); + + var result = new Dictionary(); + for (var i = 0; i < templatePathList.Count; i++) + { + var templateFilePath = Path.Combine(templatePath, templatePathList[i]); + if (!File.Exists(templateFilePath)) continue; + var tContent = File.ReadAllText(templateFilePath); + var tResult = await _viewEngine.RunCompileFromCachedAsync(tContent, data, builderAction: builder => + { + builder.AddAssemblyReferenceByName("System.Linq"); + builder.AddAssemblyReferenceByName("System.Collections"); + builder.AddUsing("System.Collections.Generic"); + builder.AddUsing("System.Linq"); + }); + result.Add(templatePathList[i]?.TrimEnd(".vm"), tResult); + } + + return result; + } + + /// + /// 获取连表的实体名和别名 + /// + /// + /// + private static (string, string) GetJoinTableStr(List configs) + { + var uploads = configs.Where(u => u.EffectType == "Upload").ToList(); + var fks = configs.Where(u => u.EffectType == "fk").ToList(); + string str = ""; // + string lowerStr = ""; // (o, i, c) + foreach (var item in uploads) + { + lowerStr += "sysFile_FK_" + item.LowerPropertyName + ","; + str += "SysFile,"; + } + foreach (var item in fks) + { + lowerStr += item.LowerFkEntityName + "_FK_" + item.LowerFkColumnName + ","; + str += item.FkEntityName + ","; + } + return (str.TrimEnd(','), lowerStr.TrimEnd(',')); + } + + /// + /// 增加菜单 + /// + /// + /// + /// + /// + /// + /// + /// + private async Task AddMenu(string className, string busName, long pid, string menuIcon, string pagePath, List tableFieldList) + { + var pPath = string.Empty; + // 若 pid=0 为顶级则创建菜单目录 + if (pid == 0) + { + // 目录 + var menuType0 = new SysMenu + { + Pid = 0, + Title = busName + "管理", + Type = MenuTypeEnum.Dir, + Icon = "robot", + Path = "/" + className.ToLower(), + Component = "Layout", + }; + // 若先前存在则删除本级和下级 + var menuList0 = await _db.Queryable().Where(u => u.Title == menuType0.Title && u.Type == menuType0.Type).ToListAsync(); + if (menuList0.Count > 0) + { + var listIds = menuList0.Select(u => u.Id).ToList(); + var childlistIds = new List(); + foreach (var item in listIds) + { + var childlist = await _db.Queryable().ToChildListAsync(u => u.Pid, item); + childlistIds.AddRange(childlist.Select(u => u.Id).ToList()); + } + listIds.AddRange(childlistIds); + await _db.Deleteable().Where(u => listIds.Contains(u.Id)).ExecuteCommandAsync(); + await _db.Deleteable().Where(u => listIds.Contains(u.MenuId)).ExecuteCommandAsync(); + } + pid = (await _db.Insertable(menuType0).ExecuteReturnEntityAsync()).Id; + } + else + { + var pMenu = await _db.Queryable().FirstAsync(u => u.Id == pid) ?? throw Oops.Oh(ErrorCodeEnum.D1505); + pPath = pMenu.Path; + } + + // 菜单 + var menuType = new SysMenu + { + Pid = pid, + Title = busName + "管理", + Name = className[..1].ToLower() + className[1..], + Type = MenuTypeEnum.Menu, + Icon = menuIcon, + Path = pPath + "/" + className.ToLower(), + Component = "/" + pagePath + "/" + className[..1].ToLower() + className[1..] + "/index", + }; + // 若先前存在则删除本级和下级 + var menuListCurrent = await _db.Queryable().Where(u => u.Title == menuType.Title && u.Type == menuType.Type).ToListAsync(); + if (menuListCurrent.Count > 0) + { + var listIds = menuListCurrent.Select(u => u.Id).ToList(); + var childListIds = new List(); + foreach (var item in listIds) + { + var childList = await _db.Queryable().ToChildListAsync(u => u.Pid, item); + childListIds.AddRange(childList.Select(u => u.Id).ToList()); + } + listIds.AddRange(childListIds); + await _db.Deleteable().Where(u => listIds.Contains(u.Id)).ExecuteCommandAsync(); + await _db.Deleteable().Where(u => listIds.Contains(u.MenuId)).ExecuteCommandAsync(); + } + + var menuPid = (await _db.Insertable(menuType).ExecuteReturnEntityAsync()).Id; + int menuOrder = 100; + // 按钮-page + var menuTypePage = new SysMenu + { + Pid = menuPid, + Title = "查询", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":page", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-detail + var menuTypeDetail = new SysMenu + { + Pid = menuPid, + Title = "详情", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":detail", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-add + var menuTypeAdd = new SysMenu + { + Pid = menuPid, + Title = "增加", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":add", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-delete + var menuTypeDelete = new SysMenu + { + Pid = menuPid, + Title = "删除", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":delete", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-update + var menuTypeUpdate = new SysMenu + { + Pid = menuPid, + Title = "编辑", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":update", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-print + var menuTypePrint = new SysMenu + { + Pid = menuPid, + Title = "打印", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":print", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-import + var menuTypeImport = new SysMenu + { + Pid = menuPid, + Title = "导入", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":import", + OrderNo = menuOrder + }; + menuOrder += 10; + + // 按钮-export + var menuTypeExport = new SysMenu + { + Pid = menuPid, + Title = "导出", + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":export", + OrderNo = menuOrder + }; + menuOrder += 10; + + var menuList = new List() { menuTypePage, menuTypeDetail, menuTypeAdd, menuTypeDelete, menuTypeUpdate, menuTypePrint, menuTypeImport, menuTypeExport }; + // 加入fk、Upload、ApiTreeSelect 等接口的权限 + // 在生成表格时,有些字段只是查询时显示,不需要填写(WhetherAddUpdate),所以这些字段没必要生成相应接口 + var fkTableList = tableFieldList.Where(u => u.EffectType == "fk" && (u.WhetherAddUpdate == "Y" || u.QueryWhether == "Y")).ToList(); + foreach (var @column in fkTableList) + { + var menuType1 = new SysMenu + { + Pid = menuPid, + Title = "外键" + @column.ColumnName, + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":" + column.FkEntityName + column.ColumnName + "Dropdown", + OrderNo = menuOrder + }; + menuOrder += 10; + menuList.Add(menuType1); + } + var treeSelectTableList = tableFieldList.Where(u => u.EffectType == "ApiTreeSelect").ToList(); + foreach (var @column in treeSelectTableList) + { + var menuType1 = new SysMenu + { + Pid = menuPid, + Title = "树型" + @column.ColumnName, + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":" + column.FkEntityName + "Tree", + OrderNo = menuOrder + }; + menuOrder += 10; + menuList.Add(menuType1); + } + var uploadTableList = tableFieldList.Where(u => u.EffectType == "Upload").ToList(); + foreach (var @column in uploadTableList) + { + var menuType1 = new SysMenu + { + Pid = menuPid, + Title = "上传" + @column.ColumnName, + Type = MenuTypeEnum.Btn, + Permission = className[..1].ToLower() + className[1..] + ":Upload" + column.ColumnName, + OrderNo = menuOrder + }; + menuOrder += 10; + menuList.Add(menuType1); + } + await _db.Insertable(menuList).ExecuteCommandAsync(); + } + + /// + /// 获取模板文件路径集合 + /// + /// + private static List GetTemplatePathList(SysCodeGen input) + { + if (input.GenerateType.Substring(1, 1).Contains('1')) + { + return new() { "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; + } + else if (input.GenerateType.Substring(1, 1).Contains('2')) + { + return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm" }; + } + else + { + return new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; + } + } + + /// + /// 获取模板文件路径集合 + /// + /// + private static List GetTemplatePathList() => new() { "Service.cs.vm", "Input.cs.vm", "Output.cs.vm", "Dto.cs.vm", "index.vue.vm", "editDialog.vue.vm", "manage.js.vm" }; + + /// + /// 设置生成文件路径 + /// + /// + /// + private List GetTargetPathList(SysCodeGen input) + { + //var backendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName, _codeGenOptions.BackendApplicationNamespace, "Service", input.TableName); + var backendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.FullName, input.NameSpace, "Service", input.TableName); + var servicePath = Path.Combine(backendPath, input.TableName + "Service.cs"); + var inputPath = Path.Combine(backendPath, "Dto", input.TableName + "Input.cs"); + var outputPath = Path.Combine(backendPath, "Dto", input.TableName + "Output.cs"); + var viewPath = Path.Combine(backendPath, "Dto", input.TableName + "Dto.cs"); + var frontendPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "views", input.PagePath); + var indexPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "index.vue");// + var formModalPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "component", "editDialog.vue"); + var apiJsPath = Path.Combine(new DirectoryInfo(App.WebHostEnvironment.ContentRootPath).Parent.Parent.FullName, _codeGenOptions.FrontRootPath, "src", "api", input.PagePath, input.TableName[..1].ToLower() + input.TableName[1..] + ".ts"); + + if (input.GenerateType.Substring(1, 1).Contains('1')) + { + // 生成到本项目(前端) + return new List() + { + indexPath, + formModalPath, + apiJsPath + }; + } + else if (input.GenerateType.Substring(1, 1).Contains('2')) + { + // 生成到本项目(后端) + return new List() + { + servicePath, + inputPath, + outputPath, + viewPath, + }; + } + else + { + // 前后端同时生成到本项目 + return new List() + { + servicePath, + inputPath, + outputPath, + viewPath, + indexPath, + formModalPath, + apiJsPath + }; + } + } + + /// + /// 设置生成文件路径 + /// + /// + /// + private List GetZipPathList(SysCodeGen input) + { + var zipPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "CodeGen", input.TableName); + + //var backendPath = Path.Combine(zipPath, _codeGenOptions.BackendApplicationNamespace, "Service", input.TableName); + var backendPath = Path.Combine(zipPath, input.NameSpace, "Service", input.TableName); + var servicePath = Path.Combine(backendPath, input.TableName + "Service.cs"); + var inputPath = Path.Combine(backendPath, "Dto", input.TableName + "Input.cs"); + var outputPath = Path.Combine(backendPath, "Dto", input.TableName + "Output.cs"); + var viewPath = Path.Combine(backendPath, "Dto", input.TableName + "Dto.cs"); + var frontendPath = Path.Combine(zipPath, _codeGenOptions.FrontRootPath, "src", "views", input.PagePath); + var indexPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "index.vue"); + var formModalPath = Path.Combine(frontendPath, input.TableName[..1].ToLower() + input.TableName[1..], "component", "editDialog.vue"); + var apiJsPath = Path.Combine(zipPath, _codeGenOptions.FrontRootPath, "src", "api", input.PagePath, input.TableName[..1].ToLower() + input.TableName[1..] + ".ts"); + if (input.GenerateType.StartsWith("11")) + { + return new List() + { + indexPath, + formModalPath, + apiJsPath + }; + } + else if (input.GenerateType.StartsWith("12")) + { + return new List() + { + servicePath, + inputPath, + outputPath, + viewPath + }; + } + else + { + return new List() + { + servicePath, + inputPath, + outputPath, + viewPath, + indexPath, + formModalPath, + apiJsPath + }; + } + } } \ No newline at end of file diff --git a/Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs b/Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs index c6640026..3a0b1b12 100644 --- a/Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs +++ b/Admin.NET/Admin.NET.Core/Service/Config/SysConfigService.cs @@ -14,12 +14,15 @@ public class SysConfigService : IDynamicApiController, ITransient { private readonly SysCacheService _sysCacheService; private readonly SqlSugarRepository _sysConfigRep; + private readonly UserManager _userManager; public SysConfigService(SysCacheService sysCacheService, - SqlSugarRepository sysConfigRep) + SqlSugarRepository sysConfigRep, + UserManager userManager) { _sysCacheService = sysCacheService; _sysConfigRep = sysConfigRep; + _userManager = userManager; } /// @@ -31,7 +34,7 @@ public class SysConfigService : IDynamicApiController, ITransient public async Task> Page(PageConfigInput input) { return await _sysConfigRep.AsQueryable() - .Where(u => u.GroupCode != "WebConfig") // 不显示 WebConfig 分组 + .WhereIF(!_userManager.SuperAdmin, u => u.GroupCode != "WebConfig") // 若非超管,不显示 WebConfig 分组 .WhereIF(!string.IsNullOrWhiteSpace(input.Name?.Trim()), u => u.Name.Contains(input.Name)) .WhereIF(!string.IsNullOrWhiteSpace(input.Code?.Trim()), u => u.Code.Contains(input.Code)) .WhereIF(!string.IsNullOrWhiteSpace(input.GroupCode?.Trim()), u => u.GroupCode.Equals(input.GroupCode)) diff --git a/Admin.NET/Admin.NET.Core/Service/OpenAccess/Dto/OpenAccessInput.cs b/Admin.NET/Admin.NET.Core/Service/OpenAccess/Dto/OpenAccessInput.cs index a3d57932..ee899629 100644 --- a/Admin.NET/Admin.NET.Core/Service/OpenAccess/Dto/OpenAccessInput.cs +++ b/Admin.NET/Admin.NET.Core/Service/OpenAccess/Dto/OpenAccessInput.cs @@ -9,7 +9,7 @@ namespace Admin.NET.Core.Service; /// /// 开放接口身份输入参数 /// -public class OpenAccessInput : BasePageInput +public class PageOpenAccessInput : BasePageInput { /// /// 身份标识 diff --git a/Admin.NET/Admin.NET.Core/Service/OpenAccess/SysOpenAccessService.cs b/Admin.NET/Admin.NET.Core/Service/OpenAccess/SysOpenAccessService.cs index b8fdf2c9..d5d92b02 100644 --- a/Admin.NET/Admin.NET.Core/Service/OpenAccess/SysOpenAccessService.cs +++ b/Admin.NET/Admin.NET.Core/Service/OpenAccess/SysOpenAccessService.cs @@ -54,7 +54,7 @@ public class SysOpenAccessService : IDynamicApiController, ITransient /// /// [DisplayName("获取开放接口身份分页列表")] - public async Task> Page(OpenAccessInput input) + public async Task> Page(PageOpenAccessInput input) { return await _sysOpenAccessRep.AsQueryable() .LeftJoin((u, a) => u.BindUserId == a.Id) diff --git a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/editDialog.vue.vm b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/editDialog.vue.vm index 24c159e7..83b5d7df 100644 --- a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/editDialog.vue.vm +++ b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/editDialog.vue.vm @@ -169,16 +169,24 @@ import { ref,onMounted, reactive } from "vue"; import { ElMessage } from "element-plus"; import type { FormRules } from "element-plus"; - +@if (@Model.IsApiService) { // 接口函数 - import { getAPI } from '/@@/utils/axios-utils'; + @:import { getAPI } from '/@@/utils/axios-utils'; // 接口 - import { @(@Model.ClassName)Api } from '/@@/api-services/api'; + @:import { @(@Model.ClassName)Api } from '/@@/api-services/api'; // 模型 - import { Update@(@Model.ClassName)Input } from '/@@/api-services/models'; + @:import { Update@(@Model.ClassName)Input } from '/@@/api-services/models'; +} else { + @:import { add@(@Model.ClassName), update@(@Model.ClassName), detail@(@Model.ClassName) } from "/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)"; + if(@Model.TableField.Any(x=>x.EffectType == "Upload")){ + @:import { Plus } from "@@element-plus/icons-vue"; + @:import { UploadRequestOptions } from "element-plus"; + @:import {@string.Join(",",Model.TableField.Where(x=>x.EffectType == "Upload").Select(x=>"upload"+x.PropertyName).ToList())} from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)'; + } +} @if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){ @:import { getConstType } from "/@@/utils/constHelper"; @@ -244,8 +252,11 @@ // 改用detail获取最新数据来编辑 let rowData = JSON.parse(JSON.stringify(row)); if (rowData.id) - //state.ruleForm = (await detail@(@Model.ClassName)(rowData.id)).data.result; - state.ruleForm = (await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DetailGet(rowData.id)).data.result; + @if (@Model.IsApiService) { + @:state.ruleForm = (await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DetailGet(rowData.id)).data.result; + } else { + @:state.ruleForm = (await detail@(@Model.ClassName)(rowData.id)).data.result; + } else state.ruleForm = rowData; state.isShowDialog = true; @@ -268,11 +279,17 @@ if (isValid) { let values = state.ruleForm; if (state.ruleForm.@(@pkFieldName) == undefined || state.ruleForm.@(@pkFieldName) == null || state.ruleForm.@(@pkFieldName) == "" || state.ruleForm.@(@pkFieldName) == 0) { - //await add@(@Model.ClassName)(values); - await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)AddPost(state.ruleForm); + @if (@Model.IsApiService) { + @:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)AddPost(state.ruleForm); + } else { + @:await add@(@Model.ClassName)(values); + } } else { - //await update@(@Model.ClassName)(values); - await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)UpdatePost(state.ruleForm); + @if (@Model.IsApiService) { + @:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)UpdatePost(state.ruleForm); + } else { + @:await update@(@Model.ClassName)(values); + } } closeDialog(); } else { @@ -324,7 +341,11 @@ if(column.WhetherAddUpdate=="N") continue; if(@column.EffectType == "Upload"){ @:const upload@(@column.PropertyName)Handle = async (options: UploadRequestOptions) => { + @if (@Model.IsApiService) { @:let list = await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)Upload@(@column.FkEntityName)PostForm(options); + } else { + @:let list = await upload@(@column.PropertyName)(options); + } @:state.ruleForm.@(column.LowerPropertyName) = res.data.result?.url; @:}; } diff --git a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm index 07501517..25e4cc6b 100644 --- a/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm +++ b/Admin.NET/Admin.NET.Web.Entry/wwwroot/Template/index.vue.vm @@ -19,25 +19,30 @@ } } else if(@column.EffectType == "DatePicker") { @: } } @@ -170,15 +177,6 @@ - @@ -191,8 +189,10 @@ import { onMounted, reactive, ref } from 'vue'; import { ElMessageBox, ElMessage } from "element-plus"; import { auth } from '/@@/utils/authFunction'; -import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table'; -import { useVxeTable } from '/@@/hooks/vxeTableOptionsHook'; + +import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table'; +import { useVxeTable } from '/@@/hooks/useVxeTableOptionsHook'; +import { Local } from '/@@/utils/storage'; @if(@Model.TableField.Any(x=>x.EffectType == "ConstSelector")){ @:import { codeToName, getConstType } from "/@@/utils/constHelper"; @@ -218,14 +218,24 @@ import PrintDialog from '/@@/views/system/print/component/hiprint/preview.vue'; import EditDialog from '/@@/views/@(@Model.PagePath)/@(@Model.LowerClassName)/component/editDialog.vue'; import ModifyRecord from '/@@/components/table/modifyRecord.vue'; +@if (@Model.IsApiService) { // 接口函数 -import { getAPI } from '/@@/utils/axios-utils'; +@:import { getAPI } from '/@@/utils/axios-utils'; // 接口 -import { @(@Model.ClassName)Api } from '/@@/api-services/api'; +@:import { @(@Model.ClassName)Api } from '/@@/api-services/api'; // 模型 -import { @(@Model.ClassName), @(@Model.ClassName)Input, @(@Model.ClassName)Output } from '/@@/api-services/models'; +@:import { @(@Model.ClassName), @(@Model.ClassName)Input, @(@Model.ClassName)Output } from '/@@/api-services/models'; + +} else { +@:import { page@(@Model.ClassName), delete@(@Model.ClassName) } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)'; +foreach (var column in Model.QueryWhetherList){ + if(@column.EffectType == "fk"){ + @:import { get@(@column.FkEntityName)@(@column.PropertyName)Dropdown } from '/@@/api/@(@Model.PagePath)/@(@Model.LowerClassName)'; + } +} +} // 子窗口对象 const xGrid = ref(); @@ -234,108 +244,112 @@ const editDialogRef = ref>(); // 变量 const state = reactive({ + showAdvanceQueryUI: false, queryParams: { + searchKey: undefined, @if(Model.QueryWhetherList.Count > 0) { @foreach (var column in Model.QueryWhetherList) { @:@(@column.LowerPropertyName): undefined, } } }, - tableParams: { - page: 1, - pageSize: 50, - field: 'id', // 默认的排序字段 - order: 'aes', // 排序方向 - descStr: 'desc', // 降序排序的关键字符 - total: 0 as any, + localPageParam: { + pageSize: 50 as number, + defaultSort: { field: 'createTime', order: 'asc', descStr: 'desc' }, }, visible: false, title: '', }); +// 本地存储参数 +const localPageParamKey = 'localPageParam:@(@Model.LowerClassName)'; + +// 改变高级查询的控件显示状态 +const changeAdvanceQueryUI = () => { + state.showAdvanceQueryUI = !state.showAdvanceQueryUI; +}; + // 表格参数配置 -const options = useVxeTable<@(@Model.ClassName)>({ - id: '@(@Model.ClassName)', - name: '@(@Model.BusName)', - columns: [ - { type: 'seq', title: '序号', width: 60, fixed: 'left' }, - @foreach (var column in Model.TableField) { - var whethersortable =column.WhetherSortable == "Y" ? "sortable: true" : "sortable: false"; - if(@column.WhetherTable == "Y") { - if(@column.EffectType == "Upload" || @column.EffectType == "fk" || @column.EffectType == "ApiTreeSelect" || @column.EffectType == "Switch" || @column.EffectType == "ConstSelector") { - if(@column.EffectType == "Upload") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "fk") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "ApiTreeSelect") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "Switch") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "ConstSelector") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } - } else if(@column.EffectType == "Select") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "EnumSelector") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else if(@column.EffectType == "DatePicker") { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, - } else { - @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', @whethersortable}, - } - } - } - { field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } }, - { title: '操作', fixed: 'right', width: 180, showOverflow: true, slots: { default: 'row_buttons' } }, - ], - enableExport: auth('@(@Model.LowerClassName):export'), - searchCallback: () => handleQuery(), - queryAllCallback: () => fetchData({ pageSize: 99999 }), -}); +const options = useVxeTable<@(@Model.ClassName)>( + { + id: '@(@Model.ClassName)', + name: '@(@Model.BusName)', + columns: [ + { type: 'seq', title: '序号', width: 60, fixed: 'left' }, + @foreach (var column in Model.TableField) { + var whethersortable =column.WhetherSortable == "Y" ? "sortable: true" : "sortable: false"; + if(@column.WhetherTable == "Y") { + if(@column.EffectType == "Upload" || @column.EffectType == "fk" || @column.EffectType == "ApiTreeSelect" || @column.EffectType == "Switch" || @column.EffectType == "ConstSelector") { + if(@column.EffectType == "Upload") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "fk") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "ApiTreeSelect") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "Switch") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "ConstSelector") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } + } else if(@column.EffectType == "Select") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "EnumSelector") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else if(@column.EffectType == "DatePicker") { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_@column.LowerPropertyName' }, @whethersortable }, + } else { + @:{ field: '@column.LowerPropertyName', title: '@column.ColumnComment', minWidth: 100, showOverflow: 'tooltip', @whethersortable}, + } + } + } + { field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } }, + { title: '操作', fixed: 'right', width: 180, showOverflow: true, slots: { default: 'row_buttons' } }, + ], + }, + // vxeGrid配置参数(此处可覆写任何参数),参考vxe-table官方文档 + { + // 代理配置 + proxyConfig: { autoLoad: true, ajax: { query: ({ page, sort }) => handleQueryApi(page, sort) } }, + // 排序配置 + sortConfig: { defaultSort: Local.get(localPageParamKey)?.defaultSort || state.localPageParam.defaultSort }, + // 分页配置 + pagerConfig: { pageSize: Local.get(localPageParamKey)?.pageSize || state.localPageParam.pageSize }, + // 工具栏配置 + toolbarConfig: { export: false }, + // 行设置 + rowConfig: { height: 80 }, + } +); // 页面初始化 onMounted(async () => { await handleQuery(); }); -// 查询操作 -const handleQuery = async (reset = false) => { - options.loading = true; - if (reset) state.tableParams.page = 1; - var res = await fetchData(null); - xGrid.value?.loadData(res.data.result?.items ?? []); - state.tableParams.total = res.data.result?.total; - options.loading = false; +// 查询api +const handleQueryApi = async (page: VxeGridPropTypes.ProxyAjaxQueryPageParams, sort: VxeGridPropTypes.ProxyAjaxQuerySortCheckedParams) => { + const params = Object.assign(state.queryParams, { page: page.currentPage, pageSize: page.pageSize, field: sort.field, order: sort.order, descStr: 'desc' }) as @(@Model.ClassName)Input; + @if (@Model.IsApiService) { + @:return getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)PagePost(params); + } else { + @:return page@(@Model.ClassName)(params); + } }; -// 获取数据 -const fetchData = async (tableParams: any) => { - let params = Object.assign(state.queryParams, state.tableParams, tableParams); - return getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)PagePost(params); +// 查询操作 +const handleQuery = async (reset = false) => { + await xGrid.value?.commitProxy('query'); }; // 重置操作 const resetQuery = () => { + state.queryParams.searchKey = undefined, @if(Model.QueryWhetherList.Count > 0) { @foreach (var column in Model.QueryWhetherList) { @:state.queryParams.@(@column.LowerPropertyName) = undefined, } } - handleQuery(true); -}; - -// 改变页码序号或页面容量 -const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => { - state.tableParams.page = currentPage; - state.tableParams.pageSize = pageSize; - handleQuery(); -}; - -// 列排序 -const sortChange = (options: any) => { - state.tableParams.field = options.field; - state.tableParams.order = options.order; - handleQuery(); + await xGrid.value?.commitProxy('reload'); }; // 打开新增页面 @@ -354,7 +368,11 @@ const handleEdit = (row: any) => { const handlePrint = async (row: any) => { state.title = '打印@(@Model.BusName)'; @if(@Model.PrintType == "custom"){ + if (@Model.IsApiService) { @:var res = await getAPI(SysPrintApi).apiSysPrintPrintNameGet('@Model.PrintName'); + } else { + @:var res = await getPrint@(@Model.ClassName)(row); + } @:var printTemplate = res.data.result as SysPrint; @:var template = JSON.parse(printTemplate.template); @:var width = template.panels[0].width; @@ -375,13 +393,31 @@ const handleDelete = (row: any) => { cancelButtonText: '取消', type: 'warning', }).then(async () => { - await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DeletePost({ id: row.id }); + @if (@Model.IsApiService) { + @:await getAPI(@(@Model.ClassName)Api).api@(@Model.ClassName)DeletePost({ id: row.id }); + } else { + @:await delete@(@Model.ClassName)(row); + } handleQuery(); ElMessage.success('删除成功'); }) .catch(() => {}); }; +// 表格事件 +const gridEvents: VxeGridListeners<@(@Model.ClassName)> = { + // 只对 pager-config 配置时有效,分页发生改变时会触发该事件 + async pageChange({ pageSize }) { + state.localPageParam.pageSize = pageSize; + Local.set(localPageParamKey, state.localPageParam); + }, + // 当排序条件发生变化时会触发该事件 + async sortChange({ field, order }) { + state.localPageParam.defaultSort = { field: field, order: order!, descStr: 'desc' }; + Local.set(localPageParamKey, state.localPageParam); + }, +}; + @foreach (var column in Model.QueryWhetherList) { @if(@column.EffectType == "fk") { @:const @LowerFirstLetter(@column.FkEntityName)@(@column.PropertyName)DropdownList = ref([]); diff --git a/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj b/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj index 78754ba0..585392af 100644 --- a/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj +++ b/Admin.NET/Plugins/Admin.NET.Plugin.ReZero/Admin.NET.Plugin.ReZero.csproj @@ -24,7 +24,7 @@ - + diff --git a/Web/api_build/build.bat b/Web/api_build/build.bat index ca72b6d4..f36d10e3 100644 --- a/Web/api_build/build.bat +++ b/Web/api_build/build.bat @@ -12,7 +12,7 @@ if exist %apiServicesPath% ( echo ================================ 开始生成 api-services ================================ -java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/All%%20Groups/swagger.json -l typescript-axios -o %apiServicesPath% +java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/Default/swagger.json -l typescript-axios -o %apiServicesPath% @rem 删除不必要的文件和文件夹 rd /s /q %apiServicesPath%.swagger-codegen diff --git a/Web/api_build/build.sh b/Web/api_build/build.sh index 75b792bc..f59ad4f0 100644 --- a/Web/api_build/build.sh +++ b/Web/api_build/build.sh @@ -14,7 +14,7 @@ fi echo "================================ 开始生成 api-services ================================" -java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/All%20Groups/swagger.json -l typescript-axios -o "${apiServicesPath}" +java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/Default/swagger.json -l typescript-axios -o "${apiServicesPath}" rm -rf "${apiServicesPath}".swagger-codegen rm -f "${apiServicesPath}".gitignore diff --git a/Web/api_build/build_all.bat b/Web/api_build/build_all.bat new file mode 100644 index 00000000..ef0b785f --- /dev/null +++ b/Web/api_build/build_all.bat @@ -0,0 +1,27 @@ +@echo off +CHCP 65001 + +set dir=%~dp0 + +set apiServicesPath=%dir%..\src\api-services\ + +if exist %apiServicesPath% ( + echo ================================ 删除目录 api-services ================================ + rd /s /q %apiServicesPath% +) + +echo ================================ 开始生成 api-services ================================ + +java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/All%20Groups/swagger.json -l typescript-axios -o %apiServicesPath% + +@rem 删除不必要的文件和文件夹 +rd /s /q %apiServicesPath%.swagger-codegen +del /q %apiServicesPath%.gitignore +del /q %apiServicesPath%.npmignore +del /q %apiServicesPath%.swagger-codegen-ignore +del /q %apiServicesPath%git_push.sh +del /q %apiServicesPath%package.json +del /q %apiServicesPath%README.md +del /q %apiServicesPath%tsconfig.json + +echo ================================ 生成结束 ================================ \ No newline at end of file diff --git a/Web/api_build/build_all.sh b/Web/api_build/build_all.sh new file mode 100644 index 00000000..75b792bc --- /dev/null +++ b/Web/api_build/build_all.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +currPath=$(pwd) +parentPath=$(dirname "$currPath") +apiServicesPath=${parentPath}/src/api-services/ + +echo "================================ 生成目录 ${apiServicesPath} ================================" + +# 判断目录是否存在 +if test -d "$apiServicesPath"; then + echo "================================ 删除目录 api-services ================================" + rm -rf "${apiServicesPath}" +fi + +echo "================================ 开始生成 api-services ================================" + +java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/All%20Groups/swagger.json -l typescript-axios -o "${apiServicesPath}" + +rm -rf "${apiServicesPath}".swagger-codegen +rm -f "${apiServicesPath}".gitignore +rm -f "${apiServicesPath}".npmignore +rm -f "${apiServicesPath}".swagger-codegen-ignore +rm -f "${apiServicesPath}"git_push.sh +rm -f "${apiServicesPath}"package.json +rm -f "${apiServicesPath}"README.md +rm -f "${apiServicesPath}"tsconfig.json + +echo "================================ 生成结束 ================================" diff --git a/Web/api_build/build_approvalFlow.bat b/Web/api_build/build_approvalFlow.bat new file mode 100644 index 00000000..6881dabb --- /dev/null +++ b/Web/api_build/build_approvalFlow.bat @@ -0,0 +1,27 @@ +@echo off +CHCP 65001 + +set dir=%~dp0 + +set apiServicesPath=%dir%..\src\api-services\_approvalFlow + +if exist %apiServicesPath% ( + echo ================================ 删除目录 api-services ================================ + rd /s /q %apiServicesPath% +) + +echo ================================ 开始生成 api-services ================================ + +java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/ApprovalFlow/swagger.json -l typescript-axios -o %apiServicesPath% + +@rem 删除不必要的文件和文件夹 +rd /s /q %apiServicesPath%.swagger-codegen +del /q %apiServicesPath%.gitignore +del /q %apiServicesPath%.npmignore +del /q %apiServicesPath%.swagger-codegen-ignore +del /q %apiServicesPath%git_push.sh +del /q %apiServicesPath%package.json +del /q %apiServicesPath%README.md +del /q %apiServicesPath%tsconfig.json + +echo ================================ 生成结束 ================================ \ No newline at end of file diff --git a/Web/api_build/build_approvalFlow.sh b/Web/api_build/build_approvalFlow.sh new file mode 100644 index 00000000..d0e651ed --- /dev/null +++ b/Web/api_build/build_approvalFlow.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +currPath=$(pwd) +parentPath=$(dirname "$currPath") +apiServicesPath=${parentPath}/src/api-services/_approvalFlow + +echo "================================ 生成目录 ${apiServicesPath} ================================" + +# 判断目录是否存在 +if test -d "$apiServicesPath"; then + echo "================================ 删除目录 api-services ================================" + rm -rf "${apiServicesPath}" +fi + +echo "================================ 开始生成 api-services ================================" + +java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/ApprovalFlow/swagger.json -l typescript-axios -o "${apiServicesPath}" + +rm -rf "${apiServicesPath}".swagger-codegen +rm -f "${apiServicesPath}".gitignore +rm -f "${apiServicesPath}".npmignore +rm -f "${apiServicesPath}".swagger-codegen-ignore +rm -f "${apiServicesPath}"git_push.sh +rm -f "${apiServicesPath}"package.json +rm -f "${apiServicesPath}"README.md +rm -f "${apiServicesPath}"tsconfig.json + +echo "================================ 生成结束 ================================" diff --git a/Web/api_build/build_dingTalk.bat b/Web/api_build/build_dingTalk.bat new file mode 100644 index 00000000..fd5fe114 --- /dev/null +++ b/Web/api_build/build_dingTalk.bat @@ -0,0 +1,27 @@ +@echo off +CHCP 65001 + +set dir=%~dp0 + +set apiServicesPath=%dir%..\src\api-services\_goView + +if exist %apiServicesPath% ( + echo ================================ 删除目录 api-services ================================ + rd /s /q %apiServicesPath% +) + +echo ================================ 开始生成 api-services ================================ + +java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/GoView/swagger.json -l typescript-axios -o %apiServicesPath% + +@rem 删除不必要的文件和文件夹 +rd /s /q %apiServicesPath%.swagger-codegen +del /q %apiServicesPath%.gitignore +del /q %apiServicesPath%.npmignore +del /q %apiServicesPath%.swagger-codegen-ignore +del /q %apiServicesPath%git_push.sh +del /q %apiServicesPath%package.json +del /q %apiServicesPath%README.md +del /q %apiServicesPath%tsconfig.json + +echo ================================ 生成结束 ================================ \ No newline at end of file diff --git a/Web/api_build/build_dingTalk.sh b/Web/api_build/build_dingTalk.sh new file mode 100644 index 00000000..3b051123 --- /dev/null +++ b/Web/api_build/build_dingTalk.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +currPath=$(pwd) +parentPath=$(dirname "$currPath") +apiServicesPath=${parentPath}/src/api-services/_goView + +echo "================================ 生成目录 ${apiServicesPath} ================================" + +# 判断目录是否存在 +if test -d "$apiServicesPath"; then + echo "================================ 删除目录 api-services ================================" + rm -rf "${apiServicesPath}" +fi + +echo "================================ 开始生成 api-services ================================" + +java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/All%20Groups/swagger.json -l typescript-axios -o "${apiServicesPath}" + +rm -rf "${apiServicesPath}".swagger-codegen +rm -f "${apiServicesPath}".gitignore +rm -f "${apiServicesPath}".npmignore +rm -f "${apiServicesPath}".swagger-codegen-ignore +rm -f "${apiServicesPath}"git_push.sh +rm -f "${apiServicesPath}"package.json +rm -f "${apiServicesPath}"README.md +rm -f "${apiServicesPath}"tsconfig.json + +echo "================================ 生成结束 ================================" diff --git a/Web/api_build/build_goView.bat b/Web/api_build/build_goView.bat new file mode 100644 index 00000000..fd5fe114 --- /dev/null +++ b/Web/api_build/build_goView.bat @@ -0,0 +1,27 @@ +@echo off +CHCP 65001 + +set dir=%~dp0 + +set apiServicesPath=%dir%..\src\api-services\_goView + +if exist %apiServicesPath% ( + echo ================================ 删除目录 api-services ================================ + rd /s /q %apiServicesPath% +) + +echo ================================ 开始生成 api-services ================================ + +java -jar %dir%swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/GoView/swagger.json -l typescript-axios -o %apiServicesPath% + +@rem 删除不必要的文件和文件夹 +rd /s /q %apiServicesPath%.swagger-codegen +del /q %apiServicesPath%.gitignore +del /q %apiServicesPath%.npmignore +del /q %apiServicesPath%.swagger-codegen-ignore +del /q %apiServicesPath%git_push.sh +del /q %apiServicesPath%package.json +del /q %apiServicesPath%README.md +del /q %apiServicesPath%tsconfig.json + +echo ================================ 生成结束 ================================ \ No newline at end of file diff --git a/Web/api_build/build_goView.sh b/Web/api_build/build_goView.sh new file mode 100644 index 00000000..ea5a77cb --- /dev/null +++ b/Web/api_build/build_goView.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +currPath=$(pwd) +parentPath=$(dirname "$currPath") +apiServicesPath=${parentPath}/src/api-services/_dingTalk + +echo "================================ 生成目录 ${apiServicesPath} ================================" + +# 判断目录是否存在 +if test -d "$apiServicesPath"; then + echo "================================ 删除目录 api-services ================================" + rm -rf "${apiServicesPath}" +fi + +echo "================================ 开始生成 api-services ================================" + +java -jar "${currPath}"/swagger-codegen-cli.jar generate -i http://localhost:5005/swagger/DingTalk/swagger.json -l typescript-axios -o "${apiServicesPath}" + +rm -rf "${apiServicesPath}".swagger-codegen +rm -f "${apiServicesPath}".gitignore +rm -f "${apiServicesPath}".npmignore +rm -f "${apiServicesPath}".swagger-codegen-ignore +rm -f "${apiServicesPath}"git_push.sh +rm -f "${apiServicesPath}"package.json +rm -f "${apiServicesPath}"README.md +rm -f "${apiServicesPath}"tsconfig.json + +echo "================================ 生成结束 ================================" diff --git a/Web/package.json b/Web/package.json index efcffd08..c9251964 100644 --- a/Web/package.json +++ b/Web/package.json @@ -2,7 +2,7 @@ "name": "admin.net.pro", "type": "module", "version": "2.4.33", - "lastBuildTime": "2024.07.09", + "lastBuildTime": "2024.07.12", "description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架", "author": "zuohuaijun", "license": "MIT", @@ -16,7 +16,7 @@ "@element-plus/icons-vue": "^2.3.1", "@logicflow/core": "^1.2.27", "@logicflow/extension": "^1.2.27", - "@microsoft/signalr": "^8.0.0", + "@microsoft/signalr": "^8.0.7", "@vue-office/docx": "^1.6.2", "@vue-office/excel": "^1.7.8", "@vue-office/pdf": "^2.0.2", @@ -49,10 +49,10 @@ "print-js": "^1.6.0", "push.js": "^1.0.12", "qrcodejs2-fixes": "^0.0.2", - "qs": "^6.12.2", + "qs": "^6.12.3", "relation-graph": "^2.2.2", "screenfull": "^6.0.2", - "sm-crypto-v2": "^1.9.0", + "sm-crypto-v2": "^1.9.1", "sortablejs": "^1.15.2", "splitpanes": "^3.1.5", "vcrontab-3": "^3.3.22", @@ -68,8 +68,8 @@ "vue-signature-pad": "^3.0.2", "vue3-tree-org": "^4.2.2", "vuedraggable": "4.0.3", - "vxe-pc-ui": "^4.0.51", - "vxe-table": "^4.7.45", + "vxe-pc-ui": "^4.0.61", + "vxe-table": "^4.7.48", "vxe-table-plugin-element": "^4.0.4", "vxe-table-plugin-export-xlsx": "^4.0.5", "xe-utils": "^3.5.28", @@ -93,8 +93,8 @@ "less": "^4.2.0", "prettier": "^3.3.2", "rollup-plugin-visualizer": "^5.12.0", - "sass": "^1.77.6", - "terser": "^5.31.1", + "sass": "^1.77.7", + "terser": "^5.31.2", "typescript": "^5.5.3", "vite": "^5.3.3", "vite-plugin-cdn-import": "^1.0.1", diff --git a/Web/src/api-services/apis/sys-code-gen-api.ts b/Web/src/api-services/apis/sys-code-gen-api.ts index 85ca3ec7..8ff15afc 100644 --- a/Web/src/api-services/apis/sys-code-gen-api.ts +++ b/Web/src/api-services/apis/sys-code-gen-api.ts @@ -26,8 +26,8 @@ import { AdminResultListTableOutput } from '../models'; import { AdminResultObject } from '../models'; import { AdminResultSqlSugarPagedListSysCodeGen } from '../models'; import { AdminResultSysCodeGen } from '../models'; -import { CodeGenInput } from '../models'; import { DeleteCodeGenInput } from '../models'; +import { PageCodeGenInput } from '../models'; import { SysCodeGen } from '../models'; import { UpdateCodeGenInput } from '../models'; /** @@ -328,11 +328,11 @@ export const SysCodeGenApiAxiosParamCreator = function (configuration?: Configur /** * * @summary 获取代码生成分页列表 🔖 - * @param {CodeGenInput} [body] + * @param {PageCodeGenInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - apiSysCodeGenPagePost: async (body?: CodeGenInput, options: AxiosRequestConfig = {}): Promise => { + apiSysCodeGenPagePost: async (body?: PageCodeGenInput, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/api/sysCodeGen/page`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, 'https://example.com'); @@ -661,11 +661,11 @@ export const SysCodeGenApiFp = function(configuration?: Configuration) { /** * * @summary 获取代码生成分页列表 🔖 - * @param {CodeGenInput} [body] + * @param {PageCodeGenInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysCodeGenPagePost(body?: CodeGenInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + async apiSysCodeGenPagePost(body?: PageCodeGenInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { const localVarAxiosArgs = await SysCodeGenApiAxiosParamCreator(configuration).apiSysCodeGenPagePost(body, options); return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; @@ -799,11 +799,11 @@ export const SysCodeGenApiFactory = function (configuration?: Configuration, bas /** * * @summary 获取代码生成分页列表 🔖 - * @param {CodeGenInput} [body] + * @param {PageCodeGenInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysCodeGenPagePost(body?: CodeGenInput, options?: AxiosRequestConfig): Promise> { + async apiSysCodeGenPagePost(body?: PageCodeGenInput, options?: AxiosRequestConfig): Promise> { return SysCodeGenApiFp(configuration).apiSysCodeGenPagePost(body, options).then((request) => request(axios, basePath)); }, /** @@ -924,12 +924,12 @@ export class SysCodeGenApi extends BaseAPI { /** * * @summary 获取代码生成分页列表 🔖 - * @param {CodeGenInput} [body] + * @param {PageCodeGenInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SysCodeGenApi */ - public async apiSysCodeGenPagePost(body?: CodeGenInput, options?: AxiosRequestConfig) : Promise> { + public async apiSysCodeGenPagePost(body?: PageCodeGenInput, options?: AxiosRequestConfig) : Promise> { return SysCodeGenApiFp(this.configuration).apiSysCodeGenPagePost(body, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/Web/src/api-services/apis/sys-ldap-api.ts b/Web/src/api-services/apis/sys-ldap-api.ts index 5bfd7ee5..8514955e 100644 --- a/Web/src/api-services/apis/sys-ldap-api.ts +++ b/Web/src/api-services/apis/sys-ldap-api.ts @@ -23,8 +23,8 @@ import { AdminResultListSysLdap } from '../models'; import { AdminResultSqlSugarPagedListSysLdap } from '../models'; import { AdminResultSysLdap } from '../models'; import { DeleteSysLdapInput } from '../models'; +import { PageSysLdapInput } from '../models'; import { SyncSysLdapInput } from '../models'; -import { SysLdapInput } from '../models'; import { UpdateSysLdapInput } from '../models'; /** * SysLdapApi - axios parameter creator @@ -226,11 +226,11 @@ export const SysLdapApiAxiosParamCreator = function (configuration?: Configurati /** * * @summary 获取系统域登录配置分页列表 🔖 - * @param {SysLdapInput} [body] + * @param {PageSysLdapInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - apiSysLdapPagePost: async (body?: SysLdapInput, options: AxiosRequestConfig = {}): Promise => { + apiSysLdapPagePost: async (body?: PageSysLdapInput, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/api/sysLdap/page`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, 'https://example.com'); @@ -482,11 +482,11 @@ export const SysLdapApiFp = function(configuration?: Configuration) { /** * * @summary 获取系统域登录配置分页列表 🔖 - * @param {SysLdapInput} [body] + * @param {PageSysLdapInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysLdapPagePost(body?: SysLdapInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + async apiSysLdapPagePost(body?: PageSysLdapInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { const localVarAxiosArgs = await SysLdapApiAxiosParamCreator(configuration).apiSysLdapPagePost(body, options); return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; @@ -586,11 +586,11 @@ export const SysLdapApiFactory = function (configuration?: Configuration, basePa /** * * @summary 获取系统域登录配置分页列表 🔖 - * @param {SysLdapInput} [body] + * @param {PageSysLdapInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysLdapPagePost(body?: SysLdapInput, options?: AxiosRequestConfig): Promise> { + async apiSysLdapPagePost(body?: PageSysLdapInput, options?: AxiosRequestConfig): Promise> { return SysLdapApiFp(configuration).apiSysLdapPagePost(body, options).then((request) => request(axios, basePath)); }, /** @@ -679,12 +679,12 @@ export class SysLdapApi extends BaseAPI { /** * * @summary 获取系统域登录配置分页列表 🔖 - * @param {SysLdapInput} [body] + * @param {PageSysLdapInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SysLdapApi */ - public async apiSysLdapPagePost(body?: SysLdapInput, options?: AxiosRequestConfig) : Promise> { + public async apiSysLdapPagePost(body?: PageSysLdapInput, options?: AxiosRequestConfig) : Promise> { return SysLdapApiFp(this.configuration).apiSysLdapPagePost(body, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/Web/src/api-services/apis/sys-open-access-api.ts b/Web/src/api-services/apis/sys-open-access-api.ts index 73067609..f04ed1b7 100644 --- a/Web/src/api-services/apis/sys-open-access-api.ts +++ b/Web/src/api-services/apis/sys-open-access-api.ts @@ -22,7 +22,7 @@ import { AdminResultSqlSugarPagedListOpenAccessOutput } from '../models'; import { AdminResultString } from '../models'; import { DeleteOpenAccessInput } from '../models'; import { GenerateSignatureInput } from '../models'; -import { OpenAccessInput } from '../models'; +import { PageOpenAccessInput } from '../models'; import { UpdateOpenAccessInput } from '../models'; /** * SysOpenAccessApi - axios parameter creator @@ -177,11 +177,11 @@ export const SysOpenAccessApiAxiosParamCreator = function (configuration?: Confi /** * * @summary 获取开放接口身份分页列表 🔖 - * @param {OpenAccessInput} [body] + * @param {PageOpenAccessInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - apiSysOpenAccessPagePost: async (body?: OpenAccessInput, options: AxiosRequestConfig = {}): Promise => { + apiSysOpenAccessPagePost: async (body?: PageOpenAccessInput, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/api/sysOpenAccess/page`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, 'https://example.com'); @@ -367,11 +367,11 @@ export const SysOpenAccessApiFp = function(configuration?: Configuration) { /** * * @summary 获取开放接口身份分页列表 🔖 - * @param {OpenAccessInput} [body] + * @param {PageOpenAccessInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + async apiSysOpenAccessPagePost(body?: PageOpenAccessInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { const localVarAxiosArgs = await SysOpenAccessApiAxiosParamCreator(configuration).apiSysOpenAccessPagePost(body, options); return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; @@ -447,11 +447,11 @@ export const SysOpenAccessApiFactory = function (configuration?: Configuration, /** * * @summary 获取开放接口身份分页列表 🔖 - * @param {OpenAccessInput} [body] + * @param {PageOpenAccessInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig): Promise> { + async apiSysOpenAccessPagePost(body?: PageOpenAccessInput, options?: AxiosRequestConfig): Promise> { return SysOpenAccessApiFp(configuration).apiSysOpenAccessPagePost(body, options).then((request) => request(axios, basePath)); }, /** @@ -519,12 +519,12 @@ export class SysOpenAccessApi extends BaseAPI { /** * * @summary 获取开放接口身份分页列表 🔖 - * @param {OpenAccessInput} [body] + * @param {PageOpenAccessInput} [body] * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof SysOpenAccessApi */ - public async apiSysOpenAccessPagePost(body?: OpenAccessInput, options?: AxiosRequestConfig) : Promise> { + public async apiSysOpenAccessPagePost(body?: PageOpenAccessInput, options?: AxiosRequestConfig) : Promise> { return SysOpenAccessApiFp(this.configuration).apiSysOpenAccessPagePost(body, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/Web/src/api-services/apis/sys-wechat-pay-api.ts b/Web/src/api-services/apis/sys-wechat-pay-api.ts index 2bb91d93..36620a41 100644 --- a/Web/src/api-services/apis/sys-wechat-pay-api.ts +++ b/Web/src/api-services/apis/sys-wechat-pay-api.ts @@ -17,9 +17,14 @@ 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 { AdminResultCreatePayTransactionOutput } from '../models'; +import { AdminResultGetRefundDomesticRefundByOutRefundNumberResponse } from '../models'; import { AdminResultObject } from '../models'; +import { AdminResultSqlSugarPagedListSysWechatPay } from '../models'; import { AdminResultSysWechatPay } from '../models'; import { AdminResultWechatPayOutput } from '../models'; +import { PageSysWechatPayInput } from '../models'; +import { RefundRequestInput } from '../models'; import { WechatPayParaInput } from '../models'; import { WechatPayTransactionInput } from '../models'; /** @@ -76,6 +81,54 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config options: localVarRequestOptions, }; }, + /** + * + * @summary 获取支付记录列表(分页) + * @param {PageSysWechatPayInput} [body] PageSysWechatPayInput + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayPagePost: async (body?: PageSysWechatPayInput, options: AxiosRequestConfig = {}): Promise => { + 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 微信支付成功回调(商户直连) 🔖 @@ -259,6 +312,104 @@ export const SysWechatPayApiAxiosParamCreator = function (configuration?: Config options: localVarRequestOptions, }; }, + /** + * + * @summary 微信支付订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id} + * @param {string} transactionId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayPayTransactionByIdTransactionIdGet: async (transactionId: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'transactionId' is not null or undefined + if (transactionId === null || transactionId === undefined) { + throw new RequiredError('transactionId','Required parameter transactionId was null or undefined when calling apiSysWechatPayPayTransactionByIdTransactionIdGet.'); + } + const localVarPath = `/api/sysWechatPay/payTransactionById/{transactionId}` + .replace(`{${"transactionId"}}`, encodeURIComponent(String(transactionId))); + // 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 商户订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no} + * @param {string} outTradeNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet: async (outTradeNumber: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'outTradeNumber' is not null or undefined + if (outTradeNumber === null || outTradeNumber === undefined) { + throw new RequiredError('outTradeNumber','Required parameter outTradeNumber was null or undefined when calling apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet.'); + } + const localVarPath = `/api/sysWechatPay/payTransactionByOutTradeNumber/{outTradeNumber}` + .replace(`{${"outTradeNumber"}}`, encodeURIComponent(String(outTradeNumber))); + // 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 微信支付统一下单获取Id(商户直连) 🔖 @@ -302,6 +453,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 查询单笔退款(通过商户退款单号) https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/query-by-out-refund-no.html + * @param {string} outRefundNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet: async (outRefundNumber: string, options: AxiosRequestConfig = {}): Promise => { + // verify required parameter 'outRefundNumber' is not null or undefined + if (outRefundNumber === null || outRefundNumber === undefined) { + throw new RequiredError('outRefundNumber','Required parameter outRefundNumber was null or undefined when calling apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet.'); + } + const localVarPath = `/api/sysWechatPay/refundByOutRefundNumber/{outRefundNumber}` + .replace(`{${"outRefundNumber"}}`, encodeURIComponent(String(outRefundNumber))); + // 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 退款申请 https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/create.html + * @param {RefundRequestInput} [body] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + apiSysWechatPayRefundPost: async (body?: RefundRequestInput, options: AxiosRequestConfig = {}): Promise => { + const localVarPath = `/api/sysWechatPay/refund`; + // 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, @@ -330,6 +578,20 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) { return axios.request(axiosRequestArgs); }; }, + /** + * + * @summary 获取支付记录列表(分页) + * @param {PageSysWechatPayInput} [body] PageSysWechatPayInput + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPagePost(body?: PageSysWechatPayInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + 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 微信支付成功回调(商户直连) 🔖 @@ -377,13 +639,41 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayPartnerTransactionPost(body, options); return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; return axios.request(axiosRequestArgs); }; }, + /** + * + * @summary 微信支付订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id} + * @param {string} transactionId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId, options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, + /** + * + * @summary 商户订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no} + * @param {string} outTradeNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber, options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, /** * * @summary 微信支付统一下单获取Id(商户直连) 🔖 @@ -391,13 +681,41 @@ export const SysWechatPayApiFp = function(configuration?: Configuration) { * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { 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 查询单笔退款(通过商户退款单号) https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/query-by-out-refund-no.html + * @param {string} outRefundNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber, options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, + /** + * + * @summary 退款申请 https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/create.html + * @param {RefundRequestInput} [body] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundPost(body?: RefundRequestInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise>> { + const localVarAxiosArgs = await SysWechatPayApiAxiosParamCreator(configuration).apiSysWechatPayRefundPost(body, options); + return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { + const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url}; + return axios.request(axiosRequestArgs); + }; + }, } }; @@ -417,6 +735,16 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig): Promise> { return SysWechatPayApiFp(configuration).apiSysWechatPayGenerateParametersForJsapiPayPost(body, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary 获取支付记录列表(分页) + * @param {PageSysWechatPayInput} [body] PageSysWechatPayInput + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPagePost(body?: PageSysWechatPayInput, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayPagePost(body, options).then((request) => request(axios, basePath)); + }, /** * * @summary 微信支付成功回调(商户直连) 🔖 @@ -452,9 +780,29 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise> { + async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise> { return SysWechatPayApiFp(configuration).apiSysWechatPayPayPartnerTransactionPost(body, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary 微信支付订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id} + * @param {string} transactionId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId: string, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary 商户订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no} + * @param {string} outTradeNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber: string, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber, options).then((request) => request(axios, basePath)); + }, /** * * @summary 微信支付统一下单获取Id(商户直连) 🔖 @@ -462,9 +810,29 @@ export const SysWechatPayApiFactory = function (configuration?: Configuration, b * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise> { + async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig): Promise> { return SysWechatPayApiFp(configuration).apiSysWechatPayPayTransactionPost(body, options).then((request) => request(axios, basePath)); }, + /** + * + * @summary 查询单笔退款(通过商户退款单号) https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/query-by-out-refund-no.html + * @param {string} outRefundNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber: string, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber, options).then((request) => request(axios, basePath)); + }, + /** + * + * @summary 退款申请 https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/create.html + * @param {RefundRequestInput} [body] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async apiSysWechatPayRefundPost(body?: RefundRequestInput, options?: AxiosRequestConfig): Promise> { + return SysWechatPayApiFp(configuration).apiSysWechatPayRefundPost(body, options).then((request) => request(axios, basePath)); + }, }; }; @@ -486,6 +854,17 @@ export class SysWechatPayApi extends BaseAPI { public async apiSysWechatPayGenerateParametersForJsapiPayPost(body?: WechatPayParaInput, options?: AxiosRequestConfig) : Promise> { return SysWechatPayApiFp(this.configuration).apiSysWechatPayGenerateParametersForJsapiPayPost(body, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary 获取支付记录列表(分页) + * @param {PageSysWechatPayInput} [body] PageSysWechatPayInput + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayPagePost(body?: PageSysWechatPayInput, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayPagePost(body, options).then((request) => request(this.axios, this.basePath)); + } /** * * @summary 微信支付成功回调(商户直连) 🔖 @@ -525,9 +904,31 @@ export class SysWechatPayApi extends BaseAPI { * @throws {RequiredError} * @memberof SysWechatPayApi */ - public async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise> { + public async apiSysWechatPayPayPartnerTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise> { return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayPartnerTransactionPost(body, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary 微信支付订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/id/{transaction_id} + * @param {string} transactionId + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId: string, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayTransactionByIdTransactionIdGet(transactionId, options).then((request) => request(this.axios, this.basePath)); + } + /** + * + * @summary 商户订单号查询(校正) https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/{out_trade_no} + * @param {string} outTradeNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber: string, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayTransactionByOutTradeNumberOutTradeNumberGet(outTradeNumber, options).then((request) => request(this.axios, this.basePath)); + } /** * * @summary 微信支付统一下单获取Id(商户直连) 🔖 @@ -536,7 +937,29 @@ export class SysWechatPayApi extends BaseAPI { * @throws {RequiredError} * @memberof SysWechatPayApi */ - public async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise> { + public async apiSysWechatPayPayTransactionPost(body?: WechatPayTransactionInput, options?: AxiosRequestConfig) : Promise> { return SysWechatPayApiFp(this.configuration).apiSysWechatPayPayTransactionPost(body, options).then((request) => request(this.axios, this.basePath)); } + /** + * + * @summary 查询单笔退款(通过商户退款单号) https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/query-by-out-refund-no.html + * @param {string} outRefundNumber + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber: string, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundByOutRefundNumberOutRefundNumberGet(outRefundNumber, options).then((request) => request(this.axios, this.basePath)); + } + /** + * + * @summary 退款申请 https://pay.weixin.qq.com/docs/merchant/apis/mini-program-payment/create.html + * @param {RefundRequestInput} [body] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SysWechatPayApi + */ + public async apiSysWechatPayRefundPost(body?: RefundRequestInput, options?: AxiosRequestConfig) : Promise> { + return SysWechatPayApiFp(this.configuration).apiSysWechatPayRefundPost(body, options).then((request) => request(this.axios, this.basePath)); + } } diff --git a/Web/src/api-services/models/add-code-gen-input.ts b/Web/src/api-services/models/add-code-gen-input.ts index e9d0db3d..a79ea25f 100644 --- a/Web/src/api-services/models/add-code-gen-input.ts +++ b/Web/src/api-services/models/add-code-gen-input.ts @@ -203,4 +203,12 @@ export interface AddCodeGenInput { * @memberof AddCodeGenInput */ generateMenu: boolean; + + /** + * 是否使用 Api Service + * + * @type {boolean} + * @memberof AddCodeGenInput + */ + isApiService?: boolean; } diff --git a/Web/src/api-services/models/add-open-access-input.ts b/Web/src/api-services/models/add-open-access-input.ts index a8b2345a..166ab4cd 100644 --- a/Web/src/api-services/models/add-open-access-input.ts +++ b/Web/src/api-services/models/add-open-access-input.ts @@ -12,6 +12,7 @@ * Do not edit the class manually. */ +import { SysUser } from './sys-user'; /** * * @@ -92,6 +93,12 @@ export interface AddOpenAccessInput { */ bindTenantId?: number; + /** + * @type {SysUser} + * @memberof AddOpenAccessInput + */ + bindUser?: SysUser; + /** * 身份标识 * diff --git a/Web/src/api-services/models/admin-result-create-pay-transaction-output.ts b/Web/src/api-services/models/admin-result-create-pay-transaction-output.ts new file mode 100644 index 00000000..50f92dcd --- /dev/null +++ b/Web/src/api-services/models/admin-result-create-pay-transaction-output.ts @@ -0,0 +1,69 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 { CreatePayTransactionOutput } from './create-pay-transaction-output'; + /** + * 全局返回结果 + * + * @export + * @interface AdminResultCreatePayTransactionOutput + */ +export interface AdminResultCreatePayTransactionOutput { + + /** + * 状态码 + * + * @type {number} + * @memberof AdminResultCreatePayTransactionOutput + */ + code?: number; + + /** + * 类型success、warning、error + * + * @type {string} + * @memberof AdminResultCreatePayTransactionOutput + */ + type?: string | null; + + /** + * 错误信息 + * + * @type {string} + * @memberof AdminResultCreatePayTransactionOutput + */ + message?: string | null; + + /** + * @type {CreatePayTransactionOutput} + * @memberof AdminResultCreatePayTransactionOutput + */ + result?: CreatePayTransactionOutput; + + /** + * 附加数据 + * + * @type {any} + * @memberof AdminResultCreatePayTransactionOutput + */ + extras?: any | null; + + /** + * 时间 + * + * @type {Date} + * @memberof AdminResultCreatePayTransactionOutput + */ + time?: Date; +} diff --git a/Web/src/api-services/models/admin-result-get-refund-domestic-refund-by-out-refund-number-response.ts b/Web/src/api-services/models/admin-result-get-refund-domestic-refund-by-out-refund-number-response.ts new file mode 100644 index 00000000..51706d2a --- /dev/null +++ b/Web/src/api-services/models/admin-result-get-refund-domestic-refund-by-out-refund-number-response.ts @@ -0,0 +1,69 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 { GetRefundDomesticRefundByOutRefundNumberResponse } from './get-refund-domestic-refund-by-out-refund-number-response'; + /** + * 全局返回结果 + * + * @export + * @interface AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ +export interface AdminResultGetRefundDomesticRefundByOutRefundNumberResponse { + + /** + * 状态码 + * + * @type {number} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + code?: number; + + /** + * 类型success、warning、error + * + * @type {string} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + type?: string | null; + + /** + * 错误信息 + * + * @type {string} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + message?: string | null; + + /** + * @type {GetRefundDomesticRefundByOutRefundNumberResponse} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + result?: GetRefundDomesticRefundByOutRefundNumberResponse; + + /** + * 附加数据 + * + * @type {any} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + extras?: any | null; + + /** + * 时间 + * + * @type {Date} + * @memberof AdminResultGetRefundDomesticRefundByOutRefundNumberResponse + */ + time?: Date; +} diff --git a/Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-wechat-pay.ts b/Web/src/api-services/models/admin-result-sql-sugar-paged-list-sys-wechat-pay.ts new file mode 100644 index 00000000..acbc3877 --- /dev/null +++ b/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 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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; +} diff --git a/Web/src/api-services/models/amount.ts b/Web/src/api-services/models/amount.ts new file mode 100644 index 00000000..64ff0985 --- /dev/null +++ b/Web/src/api-services/models/amount.ts @@ -0,0 +1,83 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 { From } from './from'; + /** + * + * + * @export + * @interface Amount + */ +export interface Amount { + + /** + * @type {number} + * @memberof Amount + */ + total?: number; + + /** + * @type {number} + * @memberof Amount + */ + refund?: number; + + /** + * @type {string} + * @memberof Amount + */ + currency?: string | null; + + /** + * @type {number} + * @memberof Amount + */ + payerTotal?: number; + + /** + * @type {number} + * @memberof Amount + */ + payerRefund?: number; + + /** + * @type {number} + * @memberof Amount + */ + settlementTotal?: number; + + /** + * @type {number} + * @memberof Amount + */ + settlementRefund?: number; + + /** + * @type {number} + * @memberof Amount + */ + discountRefund?: number; + + /** + * @type {Array} + * @memberof Amount + */ + from?: Array | null; + + /** + * @type {number} + * @memberof Amount + */ + refundFee?: number | null; +} diff --git a/Web/src/api-services/models/create-pay-transaction-output.ts b/Web/src/api-services/models/create-pay-transaction-output.ts new file mode 100644 index 00000000..3d23b334 --- /dev/null +++ b/Web/src/api-services/models/create-pay-transaction-output.ts @@ -0,0 +1,34 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 CreatePayTransactionOutput + */ +export interface CreatePayTransactionOutput { + + /** + * @type {string} + * @memberof CreatePayTransactionOutput + */ + prepayId?: string | null; + + /** + * @type {string} + * @memberof CreatePayTransactionOutput + */ + outTradeNumber?: string | null; +} diff --git a/Web/src/api-services/models/db-type.ts b/Web/src/api-services/models/db-type.ts index 44de8445..c3867028 100644 --- a/Web/src/api-services/models/db-type.ts +++ b/Web/src/api-services/models/db-type.ts @@ -42,6 +42,8 @@ export enum DbType { NUMBER_21 = 21, NUMBER_22 = 22, NUMBER_23 = 23, + NUMBER_24 = 24, + NUMBER_25 = 25, NUMBER_900 = 900 } diff --git a/Web/src/api-services/models/from.ts b/Web/src/api-services/models/from.ts new file mode 100644 index 00000000..42f776c1 --- /dev/null +++ b/Web/src/api-services/models/from.ts @@ -0,0 +1,34 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 From + */ +export interface From { + + /** + * @type {number} + * @memberof From + */ + amount?: number; + + /** + * @type {string} + * @memberof From + */ + account?: string | null; +} diff --git a/Web/src/api-services/models/get-refund-domestic-refund-by-out-refund-number-response.ts b/Web/src/api-services/models/get-refund-domestic-refund-by-out-refund-number-response.ts new file mode 100644 index 00000000..d7484ac6 --- /dev/null +++ b/Web/src/api-services/models/get-refund-domestic-refund-by-out-refund-number-response.ts @@ -0,0 +1,114 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 { Amount } from './amount'; +import { Promotion } from './promotion'; + /** + * + * + * @export + * @interface GetRefundDomesticRefundByOutRefundNumberResponse + */ +export interface GetRefundDomesticRefundByOutRefundNumberResponse { + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + code?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + message?: string | null; + + /** + * @type {{ [key: string]: any; }} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + detail?: { [key: string]: any; } | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + refundId?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + outRefundNo?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + transactionId?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + outTradeNo?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + channel?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + userReceivedAccount?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + fundsAccount?: string | null; + + /** + * @type {string} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + status?: string | null; + + /** + * @type {Date} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + successTime?: Date | null; + + /** + * @type {Date} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + createTime?: Date; + + /** + * @type {Amount} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + amount?: Amount; + + /** + * @type {Array} + * @memberof GetRefundDomesticRefundByOutRefundNumberResponse + */ + promotionDetail?: Array | null; +} diff --git a/Web/src/api-services/models/goods-detail.ts b/Web/src/api-services/models/goods-detail.ts new file mode 100644 index 00000000..93a561af --- /dev/null +++ b/Web/src/api-services/models/goods-detail.ts @@ -0,0 +1,58 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 GoodsDetail + */ +export interface GoodsDetail { + + /** + * @type {string} + * @memberof GoodsDetail + */ + merchantGoodsId?: string | null; + + /** + * @type {string} + * @memberof GoodsDetail + */ + wechatpayGoodsId?: string | null; + + /** + * @type {string} + * @memberof GoodsDetail + */ + goodsName?: string | null; + + /** + * @type {number} + * @memberof GoodsDetail + */ + unitPrice?: number; + + /** + * @type {number} + * @memberof GoodsDetail + */ + refundAmount?: number; + + /** + * @type {number} + * @memberof GoodsDetail + */ + refundQuantity?: number; +} diff --git a/Web/src/api-services/models/index.ts b/Web/src/api-services/models/index.ts index eb8039df..3dd72fd3 100644 --- a/Web/src/api-services/models/index.ts +++ b/Web/src/api-services/models/index.ts @@ -19,9 +19,11 @@ export * from './add-sys-ldap-input'; export * from './add-tenant-input'; export * from './add-user-input'; export * from './admin-result-boolean'; +export * from './admin-result-create-pay-transaction-output'; export * from './admin-result-data-set'; export * from './admin-result-data-table'; export * from './admin-result-dictionary-string-string'; +export * from './admin-result-get-refund-domestic-refund-by-out-refund-number-response'; export * from './admin-result-iaction-result'; export * from './admin-result-int32'; export * from './admin-result-int64'; @@ -82,6 +84,7 @@ export * from './admin-result-sql-sugar-paged-list-sys-online-user'; 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-wechat-pay'; export * from './admin-result-sql-sugar-paged-list-tenant-output'; export * from './admin-result-sql-sugar-paged-list-user-output'; export * from './admin-result-string'; @@ -101,6 +104,7 @@ export * from './admin-result-visual-db-table'; export * from './admin-result-wechat-pay-output'; export * from './admin-result-wx-open-id-output'; export * from './admin-result-wx-phone-output'; +export * from './amount'; export * from './api-output'; export * from './assembly'; export * from './base-api-input'; @@ -114,13 +118,13 @@ export * from './card-type-enum'; export * from './change-pwd-input'; export * from './cluster-status'; export * from './code-gen-config'; -export * from './code-gen-input'; export * from './column-ouput'; export * from './column-relation'; export * from './compare-info'; export * from './const-output'; export * from './constructor-info'; export * from './create-entity-input'; +export * from './create-pay-transaction-output'; export * from './create-seed-data-input'; export * from './culture-info'; export * from './culture-level-enum'; @@ -179,10 +183,13 @@ export * from './field-attributes'; export * from './field-info'; export * from './file-input'; export * from './file-output'; +export * from './from'; export * from './gen-auth-url-input'; export * from './gender-enum'; export * from './generate-signature-input'; export * from './generic-parameter-attributes'; +export * from './get-refund-domestic-refund-by-out-refund-number-response'; +export * from './goods-detail'; export * from './http-method-enum'; export * from './iaction-result'; export * from './icomponent'; @@ -225,8 +232,8 @@ export * from './notice-user-status-enum'; export * from './number-format-info'; export * from './oauth-user-input'; export * from './oauth-user-output'; -export * from './open-access-input'; export * from './open-access-output'; +export * from './page-code-gen-input'; export * from './page-config-input'; export * from './page-dict-data-input'; export * from './page-dict-type-input'; @@ -236,6 +243,7 @@ export * from './page-job-trigger-record-input'; export * from './page-log-input'; export * from './page-notice-input'; export * from './page-online-user-input'; +export * from './page-open-access-input'; export * from './page-plugin-input'; export * from './page-pos-input'; export * from './page-pos-output'; @@ -243,6 +251,8 @@ export * from './page-print-input'; export * from './page-region-input'; export * from './page-role-input'; export * from './page-role-output'; +export * from './page-sys-ldap-input'; +export * from './page-sys-wechat-pay-input'; export * from './page-tenant-input'; export * from './page-user-input'; export * from './parameter-attributes'; @@ -250,8 +260,10 @@ export * from './parameter-info'; export * from './platform-type-enum'; export * from './pos-output'; export * from './print-type-enum'; +export * from './promotion'; export * from './property-attributes'; export * from './property-info'; +export * from './refund-request-input'; export * from './reset-pwd-user-input'; export * from './role-api-input'; export * from './role-input'; @@ -290,6 +302,7 @@ export * from './sql-sugar-paged-list-sys-online-user'; 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-wechat-pay'; export * from './sql-sugar-paged-list-tenant-output'; export * from './sql-sugar-paged-list-user-output'; export * from './status-enum'; @@ -311,7 +324,6 @@ export * from './sys-job-detail'; export * from './sys-job-trigger'; export * from './sys-job-trigger-record'; export * from './sys-ldap'; -export * from './sys-ldap-input'; export * from './sys-log-diff'; export * from './sys-log-ex'; export * from './sys-log-op'; diff --git a/Web/src/api-services/models/member-info.ts b/Web/src/api-services/models/member-info.ts index 983879e9..b1fbee1e 100644 --- a/Web/src/api-services/models/member-info.ts +++ b/Web/src/api-services/models/member-info.ts @@ -30,12 +30,6 @@ export interface MemberInfo { */ memberType?: MemberTypes; - /** - * @type {string} - * @memberof MemberInfo - */ - name?: string | null; - /** * @type {Type} * @memberof MemberInfo @@ -48,6 +42,12 @@ export interface MemberInfo { */ reflectedType?: Type; + /** + * @type {string} + * @memberof MemberInfo + */ + name?: string | null; + /** * @type {Module} * @memberof MemberInfo diff --git a/Web/src/api-services/models/open-access-output.ts b/Web/src/api-services/models/open-access-output.ts index 1b482e70..262b2c21 100644 --- a/Web/src/api-services/models/open-access-output.ts +++ b/Web/src/api-services/models/open-access-output.ts @@ -12,6 +12,7 @@ * Do not edit the class manually. */ +import { SysUser } from './sys-user'; /** * * @@ -116,6 +117,12 @@ export interface OpenAccessOutput { */ bindUserId?: number; + /** + * @type {SysUser} + * @memberof OpenAccessOutput + */ + bindUser?: SysUser; + /** * 绑定用户账号 * diff --git a/Web/src/api-services/models/code-gen-input.ts b/Web/src/api-services/models/page-code-gen-input.ts similarity index 75% rename from Web/src/api-services/models/code-gen-input.ts rename to Web/src/api-services/models/page-code-gen-input.ts index bdaf3756..40b58fed 100644 --- a/Web/src/api-services/models/code-gen-input.ts +++ b/Web/src/api-services/models/page-code-gen-input.ts @@ -16,15 +16,15 @@ * 代码生成参数类 * * @export - * @interface CodeGenInput + * @interface PageCodeGenInput */ -export interface CodeGenInput { +export interface PageCodeGenInput { /** * 当前页码 * * @type {number} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ page?: number; @@ -32,7 +32,7 @@ export interface CodeGenInput { * 页码容量 * * @type {number} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ pageSize?: number; @@ -40,7 +40,7 @@ export interface CodeGenInput { * 排序字段 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ field?: string | null; @@ -48,7 +48,7 @@ export interface CodeGenInput { * 排序方向 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ order?: string | null; @@ -56,7 +56,7 @@ export interface CodeGenInput { * 降序排序 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ descStr?: string | null; @@ -64,7 +64,7 @@ export interface CodeGenInput { * 作者姓名 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ authorName?: string | null; @@ -72,7 +72,7 @@ export interface CodeGenInput { * 类名 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ className?: string | null; @@ -80,7 +80,7 @@ export interface CodeGenInput { * 是否移除表前缀 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ tablePrefix?: string | null; @@ -88,7 +88,7 @@ export interface CodeGenInput { * 库定位器名 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ configId?: string | null; @@ -96,7 +96,7 @@ export interface CodeGenInput { * 数据库名(保留字段) * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ dbName?: string | null; @@ -104,7 +104,7 @@ export interface CodeGenInput { * 数据库类型 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ dbType?: string | null; @@ -112,7 +112,7 @@ export interface CodeGenInput { * 数据库链接 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ connectionString?: string | null; @@ -120,7 +120,7 @@ export interface CodeGenInput { * 生成方式 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ generateType?: string | null; @@ -128,7 +128,7 @@ export interface CodeGenInput { * 数据库表名 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ tableName?: string | null; @@ -136,7 +136,7 @@ export interface CodeGenInput { * 命名空间 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ nameSpace?: string | null; @@ -144,7 +144,7 @@ export interface CodeGenInput { * 业务名(业务代码包名称) * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ busName?: string | null; @@ -152,7 +152,7 @@ export interface CodeGenInput { * 功能名(数据库表名称) * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ tableComment?: string | null; @@ -160,7 +160,7 @@ export interface CodeGenInput { * 菜单应用分类(应用编码) * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ menuApplication?: string | null; @@ -168,7 +168,7 @@ export interface CodeGenInput { * 是否生成菜单 * * @type {boolean} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ generateMenu?: boolean; @@ -176,7 +176,7 @@ export interface CodeGenInput { * 菜单父级 * * @type {number} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ menuPid?: number | null; @@ -184,7 +184,7 @@ export interface CodeGenInput { * 页面目录 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ pagePath?: string | null; @@ -192,7 +192,7 @@ export interface CodeGenInput { * 支持打印类型 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ printType?: string | null; @@ -200,7 +200,15 @@ export interface CodeGenInput { * 打印模版名称 * * @type {string} - * @memberof CodeGenInput + * @memberof PageCodeGenInput */ printName?: string | null; + + /** + * 是否使用 Api Service + * + * @type {boolean} + * @memberof PageCodeGenInput + */ + isApiService?: boolean; } diff --git a/Web/src/api-services/models/open-access-input.ts b/Web/src/api-services/models/page-open-access-input.ts similarity index 81% rename from Web/src/api-services/models/open-access-input.ts rename to Web/src/api-services/models/page-open-access-input.ts index add1f46a..5bd7749c 100644 --- a/Web/src/api-services/models/open-access-input.ts +++ b/Web/src/api-services/models/page-open-access-input.ts @@ -16,15 +16,15 @@ * 开放接口身份输入参数 * * @export - * @interface OpenAccessInput + * @interface PageOpenAccessInput */ -export interface OpenAccessInput { +export interface PageOpenAccessInput { /** * 当前页码 * * @type {number} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ page?: number; @@ -32,7 +32,7 @@ export interface OpenAccessInput { * 页码容量 * * @type {number} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ pageSize?: number; @@ -40,7 +40,7 @@ export interface OpenAccessInput { * 排序字段 * * @type {string} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ field?: string | null; @@ -48,7 +48,7 @@ export interface OpenAccessInput { * 排序方向 * * @type {string} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ order?: string | null; @@ -56,7 +56,7 @@ export interface OpenAccessInput { * 降序排序 * * @type {string} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ descStr?: string | null; @@ -64,7 +64,7 @@ export interface OpenAccessInput { * 身份标识 * * @type {string} - * @memberof OpenAccessInput + * @memberof PageOpenAccessInput */ accessKey?: string | null; } diff --git a/Web/src/api-services/models/sys-ldap-input.ts b/Web/src/api-services/models/page-sys-ldap-input.ts similarity index 82% rename from Web/src/api-services/models/sys-ldap-input.ts rename to Web/src/api-services/models/page-sys-ldap-input.ts index 7882fa15..0aa366b9 100644 --- a/Web/src/api-services/models/sys-ldap-input.ts +++ b/Web/src/api-services/models/page-sys-ldap-input.ts @@ -16,15 +16,15 @@ * 系统域登录信息配置输入参数 * * @export - * @interface SysLdapInput + * @interface PageSysLdapInput */ -export interface SysLdapInput { +export interface PageSysLdapInput { /** * 当前页码 * * @type {number} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ page?: number; @@ -32,7 +32,7 @@ export interface SysLdapInput { * 页码容量 * * @type {number} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ pageSize?: number; @@ -40,7 +40,7 @@ export interface SysLdapInput { * 排序字段 * * @type {string} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ field?: string | null; @@ -48,7 +48,7 @@ export interface SysLdapInput { * 排序方向 * * @type {string} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ order?: string | null; @@ -56,7 +56,7 @@ export interface SysLdapInput { * 降序排序 * * @type {string} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ descStr?: string | null; @@ -64,7 +64,7 @@ export interface SysLdapInput { * 关键字查询 * * @type {string} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ searchKey?: string | null; @@ -72,7 +72,7 @@ export interface SysLdapInput { * 主机 * * @type {string} - * @memberof SysLdapInput + * @memberof PageSysLdapInput */ host?: string | null; } diff --git a/Web/src/api-services/models/page-sys-wechat-pay-input.ts b/Web/src/api-services/models/page-sys-wechat-pay-input.ts new file mode 100644 index 00000000..83363150 --- /dev/null +++ b/Web/src/api-services/models/page-sys-wechat-pay-input.ts @@ -0,0 +1,102 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 PageSysWechatPayInput + */ +export interface PageSysWechatPayInput { + + /** + * 当前页码 + * + * @type {number} + * @memberof PageSysWechatPayInput + */ + page?: number; + + /** + * 页码容量 + * + * @type {number} + * @memberof PageSysWechatPayInput + */ + pageSize?: number; + + /** + * 排序字段 + * + * @type {string} + * @memberof PageSysWechatPayInput + */ + field?: string | null; + + /** + * 排序方向 + * + * @type {string} + * @memberof PageSysWechatPayInput + */ + order?: string | null; + + /** + * 降序排序 + * + * @type {string} + * @memberof PageSysWechatPayInput + */ + descStr?: string | null; + + /** + * order_id + * + * @type {number} + * @memberof PageSysWechatPayInput + */ + orderId?: number | null; + + /** + * order_status + * + * @type {number} + * @memberof PageSysWechatPayInput + */ + orderStatus?: number | null; + + /** + * out_trade_number + * + * @type {string} + * @memberof PageSysWechatPayInput + */ + outTradeNumber?: string | null; + + /** + * success_time范围 + * + * @type {Array} + * @memberof PageSysWechatPayInput + */ + successTimeRange?: Array | null; + + /** + * expire_time范围 + * + * @type {Array} + * @memberof PageSysWechatPayInput + */ + expireTimeRange?: Array | null; +} diff --git a/Web/src/api-services/models/promotion.ts b/Web/src/api-services/models/promotion.ts new file mode 100644 index 00000000..4b8e3d99 --- /dev/null +++ b/Web/src/api-services/models/promotion.ts @@ -0,0 +1,59 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 { GoodsDetail } from './goods-detail'; + /** + * + * + * @export + * @interface Promotion + */ +export interface Promotion { + + /** + * @type {string} + * @memberof Promotion + */ + promotionId?: string | null; + + /** + * @type {string} + * @memberof Promotion + */ + scope?: string | null; + + /** + * @type {string} + * @memberof Promotion + */ + type?: string | null; + + /** + * @type {number} + * @memberof Promotion + */ + amount?: number; + + /** + * @type {number} + * @memberof Promotion + */ + refundAmount?: number; + + /** + * @type {Array} + * @memberof Promotion + */ + goodsDetail?: Array | null; +} diff --git a/Web/src/api-services/models/refund-request-input.ts b/Web/src/api-services/models/refund-request-input.ts new file mode 100644 index 00000000..0d24f8f0 --- /dev/null +++ b/Web/src/api-services/models/refund-request-input.ts @@ -0,0 +1,126 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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 RefundRequestInput + */ +export interface RefundRequestInput { + + /** + * 商户订单号(原支付交易对应的付款单号) + * + * @type {string} + * @memberof RefundRequestInput + */ + outTradeNumber?: string | null; + + /** + * 原订单金额(分) + * + * @type {number} + * @memberof RefundRequestInput + */ + total?: number; + + /** + * 退款金额(分) + * + * @type {number} + * @memberof RefundRequestInput + */ + refund?: number; + + /** + * 退款原因 + * + * @type {string} + * @memberof RefundRequestInput + */ + reason?: string | null; + + /** + * 关联的商户订单号 + * + * @type {number} + * @memberof RefundRequestInput + */ + orderId?: number; + + /** + * 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) + * + * @type {number} + * @memberof RefundRequestInput + */ + orderStatus?: number; + + /** + * 关联的商户商品编码 + * + * @type {string} + * @memberof RefundRequestInput + */ + merchantGoodsId?: string | null; + + /** + * 关联的商户商品名称 + * + * @type {string} + * @memberof RefundRequestInput + */ + goodsName?: string | null; + + /** + * 关联的商户商品单价 + * + * @type {number} + * @memberof RefundRequestInput + */ + unitPrice?: number; + + /** + * 关联的商户商品退款金额 + * + * @type {number} + * @memberof RefundRequestInput + */ + refundAmount?: number; + + /** + * 关联的商户商品退货数量 + * + * @type {number} + * @memberof RefundRequestInput + */ + refundQuantity?: number; + + /** + * 附加数据 + * + * @type {string} + * @memberof RefundRequestInput + */ + attachment?: string | null; + + /** + * 备注 + * + * @type {string} + * @memberof RefundRequestInput + */ + remark?: string | null; +} diff --git a/Web/src/api-services/models/sql-sugar-paged-list-sys-wechat-pay.ts b/Web/src/api-services/models/sql-sugar-paged-list-sys-wechat-pay.ts new file mode 100644 index 00000000..dcb7a6b0 --- /dev/null +++ b/Web/src/api-services/models/sql-sugar-paged-list-sys-wechat-pay.ts @@ -0,0 +1,79 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * Admin.NET 通用权限开发平台 + * 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。
👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! + * + * 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} + * @memberof SqlSugarPagedListSysWechatPay + */ + items?: Array | null; + + /** + * 是否有上一页 + * + * @type {boolean} + * @memberof SqlSugarPagedListSysWechatPay + */ + hasPrevPage?: boolean; + + /** + * 是否有下一页 + * + * @type {boolean} + * @memberof SqlSugarPagedListSysWechatPay + */ + hasNextPage?: boolean; +} diff --git a/Web/src/api-services/models/sys-code-gen.ts b/Web/src/api-services/models/sys-code-gen.ts index 8017f169..4d68550a 100644 --- a/Web/src/api-services/models/sys-code-gen.ts +++ b/Web/src/api-services/models/sys-code-gen.ts @@ -211,4 +211,12 @@ export interface SysCodeGen { * @memberof SysCodeGen */ printName?: string | null; + + /** + * 是否使用 Api Service + * + * @type {boolean} + * @memberof SysCodeGen + */ + isApiService?: boolean; } diff --git a/Web/src/api-services/models/sys-wechat-pay.ts b/Web/src/api-services/models/sys-wechat-pay.ts index b1244f11..c7fb08f9 100644 --- a/Web/src/api-services/models/sys-wechat-pay.ts +++ b/Web/src/api-services/models/sys-wechat-pay.ts @@ -84,6 +84,22 @@ export interface SysWechatPay { */ isDelete?: boolean; + /** + * 关联的商户订单号 + * + * @type {number} + * @memberof SysWechatPay + */ + orderId?: number; + + /** + * 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) + * + * @type {number} + * @memberof SysWechatPay + */ + orderStatus?: number; + /** * 微信商户号 * diff --git a/Web/src/api-services/models/update-code-gen-input.ts b/Web/src/api-services/models/update-code-gen-input.ts index 616f60b7..fdb84a08 100644 --- a/Web/src/api-services/models/update-code-gen-input.ts +++ b/Web/src/api-services/models/update-code-gen-input.ts @@ -204,6 +204,14 @@ export interface UpdateCodeGenInput { */ printName?: string | null; + /** + * 是否使用 Api Service + * + * @type {boolean} + * @memberof UpdateCodeGenInput + */ + isApiService?: boolean; + /** * 代码生成器Id * diff --git a/Web/src/api-services/models/update-open-access-input.ts b/Web/src/api-services/models/update-open-access-input.ts index 7b4d29db..cc6cf06e 100644 --- a/Web/src/api-services/models/update-open-access-input.ts +++ b/Web/src/api-services/models/update-open-access-input.ts @@ -12,6 +12,7 @@ * Do not edit the class manually. */ +import { SysUser } from './sys-user'; /** * * @@ -92,6 +93,12 @@ export interface UpdateOpenAccessInput { */ bindTenantId?: number; + /** + * @type {SysUser} + * @memberof UpdateOpenAccessInput + */ + bindUser?: SysUser; + /** * 身份标识 * diff --git a/Web/src/api-services/models/wechat-pay-output.ts b/Web/src/api-services/models/wechat-pay-output.ts index 621ca70a..1becf524 100644 --- a/Web/src/api-services/models/wechat-pay-output.ts +++ b/Web/src/api-services/models/wechat-pay-output.ts @@ -28,6 +28,30 @@ export interface WechatPayOutput { */ openId?: string | null; + /** + * 商户(支付交易)单号,微信唯一 + * + * @type {string} + * @memberof WechatPayOutput + */ + outTradeNumber?: string | null; + + /** + * 关联的商户(商品交易)订单号 + * + * @type {number} + * @memberof WechatPayOutput + */ + orderId?: number; + + /** + * 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) + * + * @type {number} + * @memberof WechatPayOutput + */ + orderStatus?: number; + /** * 订单金额 * @@ -51,4 +75,36 @@ export interface WechatPayOutput { * @memberof WechatPayOutput */ goodsTag?: string | null; + + /** + * 支付发起时间 + * + * @type {Date} + * @memberof WechatPayOutput + */ + createTime?: Date; + + /** + * 支付完成时间 + * + * @type {Date} + * @memberof WechatPayOutput + */ + successTime?: Date; + + /** + * 交易状态(支付成功后,微信返回) + * + * @type {string} + * @memberof WechatPayOutput + */ + tradeState?: string | null; + + /** + * 交易状态描述(支付成功后,微信返回) + * + * @type {string} + * @memberof WechatPayOutput + */ + tradeStateDescription?: string | null; } diff --git a/Web/src/api-services/models/wechat-pay-transaction-input.ts b/Web/src/api-services/models/wechat-pay-transaction-input.ts index 03f3ef8e..7ca3936e 100644 --- a/Web/src/api-services/models/wechat-pay-transaction-input.ts +++ b/Web/src/api-services/models/wechat-pay-transaction-input.ts @@ -59,4 +59,20 @@ export interface WechatPayTransactionInput { * @memberof WechatPayTransactionInput */ goodsTag?: string | null; + + /** + * 关联的商户订单号 + * + * @type {number} + * @memberof WechatPayTransactionInput + */ + orderId?: number; + + /** + * 关联的商户订单付款状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) + * + * @type {number} + * @memberof WechatPayTransactionInput + */ + orderStatus?: number; } diff --git a/Web/src/hooks/setupVXETableHook.ts b/Web/src/hooks/setupVXETableHook.ts index 8c699285..332873da 100644 --- a/Web/src/hooks/setupVXETableHook.ts +++ b/Web/src/hooks/setupVXETableHook.ts @@ -8,10 +8,10 @@ import 'vxe-table-plugin-element/dist/style.css'; // Vxe UI 组件库 import VxeUI, { VxeComponentSizeType } from 'vxe-pc-ui'; import ExcelJS from 'exceljs'; -import { Local } from '../utils/storage'; +import { useThemeConfig } from '/@/stores/themeConfig'; +const vxeSize: VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini' : useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium'; export const setupVXETable = (app: App) => { - let vxeSize = getVxeTableSize(); // 加载插件 VxeUITable.use(VXETablePluginElement); VxeUITable.use(VXETablePluginExportXLSX, { ExcelJS: ExcelJS }); @@ -109,18 +109,3 @@ export const setupVXETable = (app: App) => { // app.config.globalProperties.$XSaveFile = VxeUI.saveFile // app.config.globalProperties.$XReadFile = VxeUI.readFile }; - -// 从全局主题里面获取组件大小模式 -function getVxeTableSize() { - let vxeSize: VxeComponentSizeType = 'mini'; - - let themeConfig = Local.get('themeConfig'); - if (themeConfig == null || themeConfig == undefined) return vxeSize; - - let size = themeConfig.globalComponentSize; - if (size == 'large') vxeSize = 'medium'; - else if (size == 'default') vxeSize = 'small'; - else if (size == 'small') vxeSize = 'mini'; - - return vxeSize; -} diff --git a/Web/src/hooks/useVxeTableOptionsHook.ts b/Web/src/hooks/useVxeTableOptionsHook.ts new file mode 100644 index 00000000..e8f0b0f7 --- /dev/null +++ b/Web/src/hooks/useVxeTableOptionsHook.ts @@ -0,0 +1,84 @@ +import { dayjs } from 'element-plus'; +import { reactive } from 'vue'; +import { VxeGridProps, VxeGridPropTypes, VxeComponentSizeType } from 'vxe-table'; +import { useThemeConfig } from '/@/stores/themeConfig'; +import { merge } from 'lodash-es'; + +const vxeSize: VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini' : useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium'; + +/** + * @param {String} id 表格唯一标识,为空时自动随机产生; + * @param {String} id name:表格名称,与导出文件名有关; + * @param {VxeGridPropTypes.Columns} columns 列配置; + */ +interface iVxeOption { + id?: string; + name?: string; + columns: VxeGridPropTypes.Columns; +} + +/** + * Vxe表格参数化Hook + * @param {iVxeOption} opt 参数 + * @param {VxeGridProps} extras 要覆盖的参数 + * @returns + */ +export const useVxeTable = (opt: iVxeOption, extras?: VxeGridProps) => { + // 默认参数 + opt = Object.assign({ enableExport: true, remoteExport: false }, opt); + // 创建tableId,表格id固定才可以记录调整列宽,再次刷新仍有效。 + opt.id = opt.id ? opt.id : String(new Date().getTime()); + // console.log(opt); + const options = reactive({ + id: opt.id, + height: 'auto', + autoResize: true, + size: vxeSize, + loading: false, + align: 'center', // 自动监听父元素的变化去重新计算表格(对于父元素可能存在动态变化、显示隐藏的容器中、列宽异常等场景中的可能会用到) + // data: [] as Array, + columns: opt.columns, + toolbarConfig: { + size: vxeSize, + slots: { buttons: 'toolbar_buttons', tools: 'toolbar_tools' }, + refresh: { + code: 'query', + }, + export: true, + print: true, + zoom: true, + custom: true, + }, + checkboxConfig: { range: true }, + sortConfig: { trigger: 'cell', remote: true }, + exportConfig: { + remote: false, // 设置使用服务端导出 + filename: `${opt.name}导出_${dayjs().format('YYMMDDHHmmss')}`, + }, + pagerConfig: { + enabled: true, + size: vxeSize, + pageSize: 20, + }, // 分页 + printConfig: { sheetName: '' }, + proxyConfig: { + enabled: true, + autoLoad: false, + sort: true, + props: { + list: 'data.result', // 不分页时 + result: 'data.result.items', // 分页时 + total: 'data.result.total', + message: 'data.message', + }, + }, + customConfig: { + storage: { + // 是否启用 localStorage 本地保存,会将列操作状态保留在本地(需要有 id) + visible: true, // 启用显示/隐藏列状态 + resizable: true, // 启用列宽状态 + }, + }, + }); + return extras ? merge(options, extras) : options; +}; diff --git a/Web/src/layout/component/columnsAside.vue b/Web/src/layout/component/columnsAside.vue index 7eaf2603..68b4876c 100644 --- a/Web/src/layout/component/columnsAside.vue +++ b/Web/src/layout/component/columnsAside.vue @@ -79,8 +79,9 @@ const onColumnsAsideMenuClick = async (v: RouteItem) => { if (route.path.startsWith(redirect)) mittBus.emit('setSendColumnsChildren', setSendChildren(redirect)); else router.push(redirect); } else { - if (!v.children) { + if (!v.children || v.children?.length === 0) { router.push(path); + onColumnsAsideDown(v.k); } else { // 显示子级菜单 const resData: MittMenu = setSendChildren(path); @@ -92,7 +93,7 @@ const onColumnsAsideMenuClick = async (v: RouteItem) => { // 一个路由设置自动收起菜单 // https://gitee.com/lyt-top/vue-next-admin/issues/I6HW7H - if (!v.children) themeConfig.value.isCollapse = true; + if (!v.children || v.children?.length === 0) themeConfig.value.isCollapse = true; else if (v.children.length > 1) themeConfig.value.isCollapse = false; }; // 鼠标移入时,显示当前的子级菜单 diff --git a/Web/src/stores/userInfo.ts b/Web/src/stores/userInfo.ts index 53190884..d4667bae 100644 --- a/Web/src/stores/userInfo.ts +++ b/Web/src/stores/userInfo.ts @@ -132,14 +132,16 @@ export const useUserInfo = defineStore('userInfo', { // 根据字典类型和代码取字典项 getDictItemByCode(typePCode: string, val: string) { - val = val.toString(); - if (val) { - const _val = val.toString(); - const ds = this.getDictDatasByCode(typePCode); - for (let index = 0; index < ds.length; index++) { - const element = ds[index]; - if (element.code == _val) { - return element; + if (val != undefined) { + val = val.toString(); + if (val) { + const _val = val.toString(); + const ds = this.getDictDatasByCode(typePCode); + for (let index = 0; index < ds.length; index++) { + const element = ds[index]; + if (element.code == _val) { + return element; + } } } } diff --git a/Web/src/theme/element.scss b/Web/src/theme/element.scss index 83daf5b7..47524694 100644 --- a/Web/src/theme/element.scss +++ b/Web/src/theme/element.scss @@ -376,13 +376,13 @@ /* Table 表格 element plus 2.2.0 版本 ------------------------------- */ .el-table { + // 表头背景色 + --el-table-header-bg-color: var(--next-bg-main-color); + .el-button.is-text { padding: 0; } - // 表头背景色 - --el-table-header-bg-color: var(--next-bg-main-color); - // 表头字体颜色 thead { color: var(--el-text-color-regular); diff --git a/Web/src/theme/vxeTable.scss b/Web/src/theme/vxeTable.scss index 2482ce3b..a1be7244 100644 --- a/Web/src/theme/vxeTable.scss +++ b/Web/src/theme/vxeTable.scss @@ -36,10 +36,11 @@ .vxe-cell { padding-left: 5px !important; padding-right: 5px !important; + user-select: text !important; + .el-button { padding: 0 !important; } - user-select: text !important; } .vxe-pager.size--mini { diff --git a/Web/src/views/about/index.vue b/Web/src/views/about/index.vue index f3864372..d5dd711a 100644 --- a/Web/src/views/about/index.vue +++ b/Web/src/views/about/index.vue @@ -5,8 +5,8 @@ 简介(About) - 基于 .NET6 (Furion/SqlSugar) 实现的通用权限开发框架,前端采用 - Vue3+Element-plus+Vite5,整合众多优秀技术和框架,模块插件式开发。集成多租户、缓存、数据校验、鉴权、事件总线、动态API、通讯、远程请求、任务调度、打印等众多黑科技。代码结构简单清晰,注释详尽,易于上手与二次开发,即便是复杂业务逻辑也能迅速实现,真正实现“开箱即用”。 + 🔥基于 .NET 6/8 (Furion/SqlSugar) 实现的通用权限开发框架,前端采用 + Vue3/Element-plus,代码简洁、易扩展。整合最新技术,模块插件式开发,前后端分离,开箱即用。集成多租户、缓存、数据校验、鉴权、事件总线、动态API、通讯、远程请求、任务调度、打印等众多黑科技。让开发更简单、更通用、更流行! diff --git a/Web/src/views/login/component/account.vue b/Web/src/views/login/component/account.vue index 1407af75..a22804a5 100644 --- a/Web/src/views/login/component/account.vue +++ b/Web/src/views/login/component/account.vue @@ -283,6 +283,8 @@ defineExpose({ saveTokenAndInitRoutes });