😎1、调整登录逻辑 2、清理无效代码
This commit is contained in:
parent
d6b96fb751
commit
dc551bc59c
@ -99,7 +99,7 @@ public class AppAuthService : IDynamicApiController, ITransient
|
|||||||
// 登录成功则清空密码错误次数
|
// 登录成功则清空密码错误次数
|
||||||
_sysCacheService.Remove(keyPasswordErrorTimes);
|
_sysCacheService.Remove(keyPasswordErrorTimes);
|
||||||
|
|
||||||
return await CreateToken(user, input.LoginMode);
|
return await CreateToken(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -148,7 +148,7 @@ public class AppAuthService : IDynamicApiController, ITransient
|
|||||||
var user = await _sysUserRep.AsQueryable().Includes(u => u.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone));
|
var user = await _sysUserRep.AsQueryable().Includes(u => u.SysOrg).ClearFilter().FirstAsync(u => u.Phone.Equals(input.Phone));
|
||||||
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||||
|
|
||||||
return await CreateToken(user, input.LoginMode);
|
return await CreateToken(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -158,7 +158,7 @@ public class AppAuthService : IDynamicApiController, ITransient
|
|||||||
/// <param name="loginMode"></param>
|
/// <param name="loginMode"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public virtual async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode)
|
public virtual async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode = LoginModeEnum.APP)
|
||||||
{
|
{
|
||||||
// 单用户登录
|
// 单用户登录
|
||||||
await _sysOnlineUserService.SingleLogin(user.Id, loginMode);
|
await _sysOnlineUserService.SingleLogin(user.Id, loginMode);
|
||||||
|
|||||||
@ -68,13 +68,16 @@ public class DictAttribute : ValidationAttribute, ITransient
|
|||||||
return ValidationResult.Success;
|
return ValidationResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 先尝试从 ValidationContext 的依赖注入容器中拿服务,再从全局的 App 容器中获取
|
// 先尝试从 ValidationContext 的依赖注入容器中拿服务,拿不到或类型不匹配时,再从全局的 App 容器中获取
|
||||||
if (validationContext.GetService(typeof(SysDictDataService)) is not SysDictDataService sysDictDataService)
|
if (validationContext.GetService(typeof(SysDictTypeService)) is not SysDictTypeService sysDictDataService)
|
||||||
sysDictDataService = App.GetRequiredService<SysDictDataService>();
|
sysDictDataService = App.GetRequiredService<SysDictTypeService>();
|
||||||
|
|
||||||
// 获取字典值列表
|
// 获取字典值列表
|
||||||
var dictDataList = sysDictDataService.GetDataList(DictTypeCode).GetAwaiter().GetResult();
|
var dictDataList = sysDictDataService.GetDataList(new GetDataDictTypeInput { Code = DictTypeCode }).GetAwaiter().GetResult();
|
||||||
|
|
||||||
// 使用 HashSet 来提高查找效率
|
// 使用 HashSet 来提高查找效率
|
||||||
var dictHash = new HashSet<string>(dictDataList.Select(u => u.Code));
|
var dictHash = new HashSet<string>(dictDataList.Select(u => u.Code));
|
||||||
|
|
||||||
if (!dictHash.Contains(valueAsString)) return new ValidationResult($"提示:{ErrorMessage}|字典【{DictTypeCode}】不包含【{valueAsString}】!");
|
if (!dictHash.Contains(valueAsString)) return new ValidationResult($"提示:{ErrorMessage}|字典【{DictTypeCode}】不包含【{valueAsString}】!");
|
||||||
|
|
||||||
return ValidationResult.Success;
|
return ValidationResult.Success;
|
||||||
|
|||||||
@ -26,11 +26,6 @@ public class SqlSugarConst
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public const string PrimaryKey = "Id";
|
public const string PrimaryKey = "Id";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 默认应用Id
|
|
||||||
/// </summary>
|
|
||||||
public const long DefaultAppId = 1300000000001;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 默认租户Id
|
/// 默认租户Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统应用表
|
|
||||||
/// </summary>
|
|
||||||
[SysTable]
|
|
||||||
[SugarTable(null, "系统应用表")]
|
|
||||||
public partial class SysApp : EntityBase
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 名称
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "名称", Length = 32), Required, MaxLength(32)]
|
|
||||||
public virtual string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 图标
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "图标", Length = 256), Required, MaxLength(256)]
|
|
||||||
public virtual string? Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 标题
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "标题", Length = 32), MaxLength(32)]
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副标题
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "副标题", Length = 32), MaxLength(32)]
|
|
||||||
public string ViceTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副描述
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "副描述", Length = 64), MaxLength(64)]
|
|
||||||
public string? ViceDesc { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 水印
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "水印", Length = 32), MaxLength(32)]
|
|
||||||
public string? Watermark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 版权信息
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "版权信息", Length = 64), MaxLength(64)]
|
|
||||||
public string? Copyright { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ICP备案号
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "ICP备案号", Length = 32), MaxLength(32)]
|
|
||||||
public string? Icp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 排序
|
|
||||||
/// </summary>
|
|
||||||
[IgnoreUpdateSeedColumn]
|
|
||||||
[SugarColumn(ColumnDescription = "排序")]
|
|
||||||
public int OrderNo { get; set; } = 100;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "备注", Length = 256), MaxLength(256)]
|
|
||||||
public string? Remark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用租户
|
|
||||||
/// </summary>
|
|
||||||
[Navigate(NavigateType.OneToMany, nameof(SysTenant.AppId))]
|
|
||||||
public List<SysTenant> TenantList { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统应用菜单表
|
|
||||||
/// </summary>
|
|
||||||
[SugarTable(null, "系统应用菜单表")]
|
|
||||||
[SysTable]
|
|
||||||
public partial class SysAppMenu : EntityBaseId
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 应用Id
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "应用Id")]
|
|
||||||
public long AppId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用
|
|
||||||
/// </summary>
|
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
|
||||||
[System.Text.Json.Serialization.JsonIgnore]
|
|
||||||
[Navigate(NavigateType.OneToOne, nameof(AppId))]
|
|
||||||
public SysApp SysApp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 菜单Id
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "菜单Id")]
|
|
||||||
public long MenuId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 菜单
|
|
||||||
/// </summary>
|
|
||||||
[Navigate(NavigateType.OneToOne, nameof(MenuId))]
|
|
||||||
public SysMenu SysMenu { get; set; }
|
|
||||||
}
|
|
||||||
@ -14,23 +14,9 @@ namespace Admin.NET.Core;
|
|||||||
public partial class SysTenant : EntityBase
|
public partial class SysTenant : EntityBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 应用Id
|
/// 租管用户Id
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(ColumnDescription = "应用Id", DefaultValue = "1300000000001")]
|
[SugarColumn(ColumnDescription = "租管用户Id")]
|
||||||
public long? AppId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用
|
|
||||||
/// </summary>
|
|
||||||
[Newtonsoft.Json.JsonIgnore]
|
|
||||||
[System.Text.Json.Serialization.JsonIgnore]
|
|
||||||
[Navigate(NavigateType.OneToOne, nameof(AppId))]
|
|
||||||
public SysApp SysApp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 用户Id
|
|
||||||
/// </summary>
|
|
||||||
[SugarColumn(ColumnDescription = "用户Id")]
|
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -21,18 +21,18 @@ public enum GenderEnum
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 男性
|
/// 男性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("男性")]
|
[Description("男性"), Theme("success")]
|
||||||
Male = 1,
|
Male = 1,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 女性
|
/// 女性
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("女性")]
|
[Description("女性"), Theme("danger")]
|
||||||
Female = 2,
|
Female = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 未说明的性别
|
/// 未说明的性别
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("未说明的性别"), Theme("info")]
|
[Description("未说明的性别"), Theme("warning")]
|
||||||
Unspecified = 9
|
Unspecified = 9
|
||||||
}
|
}
|
||||||
@ -58,5 +58,17 @@ public enum UserEventTypeEnum
|
|||||||
/// 解除登录锁定
|
/// 解除登录锁定
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("解除登录锁定")]
|
[Description("解除登录锁定")]
|
||||||
UnlockLogin = 7
|
UnlockLogin = 7,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统登录
|
||||||
|
/// </summary>
|
||||||
|
[Description("系统登录")]
|
||||||
|
Login = 8,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 系统退出
|
||||||
|
/// </summary>
|
||||||
|
[Description("系统退出")]
|
||||||
|
Logout = 9,
|
||||||
}
|
}
|
||||||
@ -1,23 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统应用菜单表种子数据
|
|
||||||
/// </summary>
|
|
||||||
public class SysAppMenuSeedData : ISqlSugarEntitySeedData<SysAppMenu>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 种子数据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IEnumerable<SysAppMenu> HasData()
|
|
||||||
{
|
|
||||||
long id = SqlSugarConst.DefaultAppId;
|
|
||||||
return new SysMenuSeedData().HasData().Select(u => new SysAppMenu { Id = id++, AppId = SqlSugarConst.DefaultAppId, MenuId = u.Id });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统应用表种子数据
|
|
||||||
/// </summary>
|
|
||||||
public class SysAppSeedData : ISqlSugarEntitySeedData<SysApp>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 种子数据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public IEnumerable<SysApp> HasData()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
[
|
|
||||||
new SysApp{ Id=SqlSugarConst.DefaultAppId, Name="默认应用", Logo="/upload/logo.png", Title="Admin.NET", ViceTitle="Admin.NET", ViceDesc="站在巨人肩膀上的 .NET 通用权限开发框架", Watermark="Admin.NET", Copyright="Copyright \u00a9 2021-present Admin.NET All rights reserved.", Icp="省ICP备12345678号", Remark="系统默认应用", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -21,7 +21,19 @@ public class SysTenantSeedData : ISqlSugarEntitySeedData<SysTenant>
|
|||||||
|
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
new SysTenant{ Id=SqlSugarConst.DefaultTenantId, AppId=SqlSugarConst.DefaultTenantId, OrgId=SqlSugarConst.DefaultTenantId, UserId=1300000000111, Host="gitee.com", TenantType=TenantTypeEnum.Id, DbType=defaultDbConfig.DbType, Connection=defaultDbConfig.ConnectionString, ConfigId=SqlSugarConst.MainConfigId, Remark="系统默认", CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
new SysTenant
|
||||||
|
{
|
||||||
|
Id=SqlSugarConst.DefaultTenantId,
|
||||||
|
OrgId=SqlSugarConst.DefaultTenantId,
|
||||||
|
UserId=1300000000111,
|
||||||
|
Host="gitee.com",
|
||||||
|
TenantType=TenantTypeEnum.Id,
|
||||||
|
DbType=defaultDbConfig.DbType,
|
||||||
|
Connection=defaultDbConfig.ConnectionString,
|
||||||
|
ConfigId=SqlSugarConst.MainConfigId,
|
||||||
|
Remark="系统默认",
|
||||||
|
CreateTime=DateTime.Parse("2022-02-10 00:00:00")
|
||||||
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,11 +23,11 @@ public class SysUserSeedData : ISqlSugarEntitySeedData<SysUser>
|
|||||||
return
|
return
|
||||||
[
|
[
|
||||||
new SysUser{ Id=1300000000101, Account="superadmin", Password=encryptPassword, NickName="超级管理员", RealName="超级管理员", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SuperAdmin, Remark="超级管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000101, Account="superadmin", Password=encryptPassword, NickName="超级管理员", RealName="超级管理员", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SuperAdmin, Remark="超级管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
new SysUser{ Id=1300000000111, Account="admin", Password=encryptPassword, NickName="系统管理员", RealName="系统管理员", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SysAdmin, Remark="系统管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId, PosId=1300000000102, TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000111, Account="admin", Password=encryptPassword, NickName="系统管理员", RealName="系统管理员", Phone="18012345677", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Male, AccountType=AccountTypeEnum.SysAdmin, Remark="系统管理员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId, PosId=1300000000102, TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
new SysUser{ Id=1300000000112, Account="user1", Password=encryptPassword, NickName="部门主管", RealName="部门主管", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门主管", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 1, PosId=1300000000108, TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000112, Account="user1", Password=encryptPassword, NickName="部门主管", RealName="部门主管", Phone="18012345676", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门主管", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 1, PosId=1300000000108, TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
new SysUser{ Id=1300000000113, Account="user2", Password=encryptPassword, NickName="部门职员", RealName="部门职员", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门职员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 2, PosId=1300000000110, TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000113, Account="user2", Password=encryptPassword, NickName="部门职员", RealName="部门职员", Phone="18012345675", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="部门职员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 2, PosId=1300000000110, TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
new SysUser{ Id=1300000000114, Account="user3", Password=encryptPassword, NickName="普通用户", RealName="普通用户", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="普通用户", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 3, PosId=1300000000115, TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000114, Account="user3", Password=encryptPassword, NickName="普通用户", RealName="普通用户", Phone="18012345674", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.NormalUser, Remark="普通用户", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 3, PosId=1300000000115, TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
new SysUser{ Id=1300000000115, Account="user4", Password=encryptPassword, NickName="其他", RealName="其他", Phone="18012345678", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.Member, Remark="会员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 4, PosId=1300000000116, TenantId=SqlSugarConst.DefaultTenantId },
|
new SysUser{ Id=1300000000115, Account="user4", Password=encryptPassword, NickName="其他", RealName="其他", Phone="18012345673", Birthday=DateTime.Parse("2000-01-01"), Sex=GenderEnum.Female, AccountType=AccountTypeEnum.Member, Remark="会员", CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrgId=SqlSugarConst.DefaultTenantId + 4, PosId=1300000000116, TenantId=SqlSugarConst.DefaultTenantId },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,173 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core.Service;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用基础输入参数
|
|
||||||
/// </summary>
|
|
||||||
public class SysAppInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 主键Id
|
|
||||||
/// </summary>
|
|
||||||
public virtual long? Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 名称
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "名称不能为空")]
|
|
||||||
public virtual string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 标题
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "标题不能为空")]
|
|
||||||
public virtual string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副标题
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "副标题不能为空")]
|
|
||||||
public virtual string ViceTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副描述
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? ViceDesc { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 水印
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? Watermark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 版权信息
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? Copyright { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ICP备案号
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? Icp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 排序
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "排序不能为空")]
|
|
||||||
public virtual int? OrderNo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? Remark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 图标
|
|
||||||
/// </summary>
|
|
||||||
public virtual string? Logo { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 增加应用输入参数
|
|
||||||
/// </summary>
|
|
||||||
public class AddSysAppInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 图标
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "Logo不能为空")]
|
|
||||||
public string Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 名称
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "名称不能为空")]
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 标题
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "标题不能为空")]
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副标题
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "副标题不能为空")]
|
|
||||||
public string ViceTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副描述
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "副描述不能为空")]
|
|
||||||
public string ViceDesc { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 水印
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "水印不能为空")]
|
|
||||||
public string Watermark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 版权信息
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "版权信息不能为空")]
|
|
||||||
public string Copyright { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ICP备案号
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "备案号不能为空")]
|
|
||||||
public string Icp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 排序
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "排序不能为空")]
|
|
||||||
public int OrderNo { get; set; } = 100;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
[MaxLength(256, ErrorMessage = "备注字符长度不能超过256")]
|
|
||||||
public string Remark { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新应用输入参数
|
|
||||||
/// </summary>
|
|
||||||
public class UpdateSysAppInput : AddSysAppInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 主键Id
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "主键Id不能为空")]
|
|
||||||
public long Id { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 授权应用菜单
|
|
||||||
/// </summary>
|
|
||||||
public class UpdateAppMenuInput : BaseIdInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 菜单Id集合
|
|
||||||
/// </summary>
|
|
||||||
public List<long> MenuIdList { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户iId
|
|
||||||
/// </summary>
|
|
||||||
public class ChangeAppInput : BaseIdInput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 租户Id
|
|
||||||
/// </summary>
|
|
||||||
[Required(ErrorMessage = "租户不能为空")]
|
|
||||||
public long TenantId { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core.Service;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 应用输出参数
|
|
||||||
/// </summary>
|
|
||||||
public class SysAppOutput
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 主键Id
|
|
||||||
/// </summary>
|
|
||||||
public long Id { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 名称
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 图标
|
|
||||||
/// </summary>
|
|
||||||
public string? Logo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 标题
|
|
||||||
/// </summary>
|
|
||||||
public string Title { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副标题
|
|
||||||
/// </summary>
|
|
||||||
public string ViceTitle { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 副描述
|
|
||||||
/// </summary>
|
|
||||||
public string? ViceDesc { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 水印
|
|
||||||
/// </summary>
|
|
||||||
public string? Watermark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 版权信息
|
|
||||||
/// </summary>
|
|
||||||
public string? Copyright { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// ICP备案号
|
|
||||||
/// </summary>
|
|
||||||
public string? Icp { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 排序
|
|
||||||
/// </summary>
|
|
||||||
public int OrderNo { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 备注
|
|
||||||
/// </summary>
|
|
||||||
public string? Remark { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建时间
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? CreateTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新时间
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? UpdateTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建者Id
|
|
||||||
/// </summary>
|
|
||||||
public long? CreateUserId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建者姓名
|
|
||||||
/// </summary>
|
|
||||||
public string? CreateUserName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 修改者Id
|
|
||||||
/// </summary>
|
|
||||||
public long? UpdateUserId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 修改者姓名
|
|
||||||
/// </summary>
|
|
||||||
public string? UpdateUserName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 软删除
|
|
||||||
/// </summary>
|
|
||||||
public bool IsDelete { get; set; }
|
|
||||||
}
|
|
||||||
@ -1,183 +0,0 @@
|
|||||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
|
||||||
//
|
|
||||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
|
||||||
//
|
|
||||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
|
||||||
|
|
||||||
namespace Admin.NET.Core.Service;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 系统应用服务 🧩
|
|
||||||
/// </summary>
|
|
||||||
[ApiDescriptionSettings(Name = "SysApp", Order = 495, Description = "系统应用")]
|
|
||||||
public class SysAppService : IDynamicApiController, ITransient
|
|
||||||
{
|
|
||||||
private readonly SqlSugarRepository<SysAppMenu> _sysAppMenuRep;
|
|
||||||
private readonly SqlSugarRepository<SysApp> _sysAppRep;
|
|
||||||
private readonly SysAuthService _sysAuthService;
|
|
||||||
private readonly UserManager _userManager;
|
|
||||||
|
|
||||||
public SysAppService(SqlSugarRepository<SysApp> sysAppRep,
|
|
||||||
SqlSugarRepository<SysAppMenu> sysAppMenuRep,
|
|
||||||
SysAuthService sysAuthService,
|
|
||||||
UserManager userManager)
|
|
||||||
{
|
|
||||||
_sysAppRep = sysAppRep;
|
|
||||||
_userManager = userManager;
|
|
||||||
_sysAppMenuRep = sysAppMenuRep;
|
|
||||||
_sysAuthService = sysAuthService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 分页查询应用 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("分页查询应用")]
|
|
||||||
[ApiDescriptionSettings(Name = "Page"), HttpPost]
|
|
||||||
public async Task<SqlSugarPagedList<SysAppOutput>> Page(BasePageInput input)
|
|
||||||
{
|
|
||||||
input.Keyword = input.Keyword?.Trim();
|
|
||||||
var query = _sysAppRep.AsQueryable()
|
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Keyword), u => u.Name.Contains(input.Keyword) ||
|
|
||||||
u.Title.Contains(input.Keyword) || u.ViceTitle.Contains(input.Keyword) ||
|
|
||||||
u.ViceDesc.Contains(input.Keyword) || u.Remark.Contains(input.Keyword))
|
|
||||||
.OrderBy(u => new { u.OrderNo, u.Id })
|
|
||||||
.Select<SysAppOutput>();
|
|
||||||
return await query.OrderBuilder(input).ToPagedListAsync(input.Page, input.PageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 增加应用 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("增加应用")]
|
|
||||||
[ApiDescriptionSettings(Name = "Add"), HttpPost]
|
|
||||||
public async Task<long> Add(AddSysAppInput input)
|
|
||||||
{
|
|
||||||
var entity = input.Adapt<SysApp>();
|
|
||||||
return await _sysAppRep.InsertAsync(entity) ? entity.Id : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新应用 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("更新应用")]
|
|
||||||
[ApiDescriptionSettings(Name = "Update"), HttpPost]
|
|
||||||
public async Task Update(UpdateSysAppInput input)
|
|
||||||
{
|
|
||||||
_ = await _sysAppRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
|
||||||
|
|
||||||
var entity = input.Adapt<SysApp>();
|
|
||||||
await _sysAppRep.AsUpdateable(entity).ExecuteCommandAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除应用 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("删除应用")]
|
|
||||||
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
|
|
||||||
public async Task Delete(BaseIdInput input)
|
|
||||||
{
|
|
||||||
var entity = await _sysAppRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
|
||||||
|
|
||||||
// 禁止删除存在关联租户的应用
|
|
||||||
if (await _sysAppRep.Context.Queryable<SysTenant>().AnyAsync(u => u.AppId == input.Id)) throw Oops.Oh(ErrorCodeEnum.A1001);
|
|
||||||
|
|
||||||
// 禁止删除存在关联菜单的应用
|
|
||||||
if (await _sysAppMenuRep.AsQueryable().AnyAsync(u => u.AppId == input.Id)) throw Oops.Oh(ErrorCodeEnum.A1002);
|
|
||||||
|
|
||||||
await _sysAppRep.DeleteAsync(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取应用菜单 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("获取应用菜单")]
|
|
||||||
public async Task<List<long>> GetMenuList([FromQuery] long id)
|
|
||||||
{
|
|
||||||
return await _sysAppMenuRep.AsQueryable().Where(u => u.AppId == id).Select(u => u.MenuId).ToListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 授权应用菜单 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[UnitOfWork]
|
|
||||||
[DisplayName("授权应用菜单")]
|
|
||||||
public async Task GrantMenu(UpdateAppMenuInput input)
|
|
||||||
{
|
|
||||||
input.MenuIdList ??= new();
|
|
||||||
|
|
||||||
await _sysAppMenuRep.DeleteAsync(u => u.AppId == input.Id);
|
|
||||||
|
|
||||||
var list = input.MenuIdList.Select(id => new SysAppMenu { AppId = input.Id, MenuId = id }).ToList();
|
|
||||||
|
|
||||||
await _sysAppMenuRep.InsertRangeAsync(list);
|
|
||||||
|
|
||||||
// 清除应用下其他模块越权的授权数据,包括角色菜单,用户收藏菜单
|
|
||||||
var tenantIds = await _sysAppRep.Context.Queryable<SysTenant>().Where(u => u.AppId == input.Id).Select(u => u.Id).ToListAsync();
|
|
||||||
var roleIds = await _sysAppRep.Context.Queryable<SysRole>().Where(u => tenantIds.Contains((long)u.TenantId)).Select(u => u.Id).ToListAsync();
|
|
||||||
var userIds = await _sysAppRep.Context.Queryable<SysUser>().Where(u => tenantIds.Contains((long)u.TenantId)).Select(u => u.Id).ToListAsync();
|
|
||||||
await _sysAppRep.Context.Deleteable<SysRoleMenu>().Where(u => roleIds.Contains(u.RoleId) && !input.MenuIdList.Contains(u.MenuId)).ExecuteCommandAsync();
|
|
||||||
await _sysAppRep.Context.Deleteable<SysUserMenu>().Where(u => userIds.Contains(u.UserId) && !input.MenuIdList.Contains(u.MenuId)).ExecuteCommandAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取应用数据 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("获取应用数据")]
|
|
||||||
public async Task<dynamic> GetAppData()
|
|
||||||
{
|
|
||||||
var list = await _sysAppRep.AsQueryable().Includes(u => u.TenantList).ToListAsync();
|
|
||||||
return list.Where(u => u.TenantList.Count > 0).Select(u => new
|
|
||||||
{
|
|
||||||
u.Id,
|
|
||||||
Value = u.Id,
|
|
||||||
Label = u.Name,
|
|
||||||
Children = u.TenantList.Select(t => new
|
|
||||||
{
|
|
||||||
t.Id,
|
|
||||||
Value = t.Id,
|
|
||||||
Label = t.Host ?? (t.Id + ""),
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 切换应用 🔖
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DisplayName("切换应用")]
|
|
||||||
public async Task<LoginOutput> ChangeApp(ChangeAppInput input)
|
|
||||||
{
|
|
||||||
_ = await _sysAppRep.Context.Queryable<SysTenant>().FirstAsync(u => u.Id == input.TenantId) ?? throw Oops.Oh(ErrorCodeEnum.Z1003);
|
|
||||||
_ = await _sysAppRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
|
||||||
|
|
||||||
var user = await _sysAppRep.Context.Queryable<SysUser>().FirstAsync(u => u.Id == _userManager.UserId);
|
|
||||||
user.TenantId = input.TenantId;
|
|
||||||
|
|
||||||
return await _sysAuthService.CreateToken(user, input.Id, LoginModeEnum.PC);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取当前应用信息
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
[NonAction]
|
|
||||||
public async Task<SysApp> GetCurrentAppInfo()
|
|
||||||
{
|
|
||||||
var appId = _userManager.AppId > 0 ? _userManager.AppId : SqlSugarConst.DefaultAppId;
|
|
||||||
return await _sysAppRep.GetFirstAsync(u => u.Id == appId) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -73,5 +73,5 @@ public class LoginPhoneInput
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 登录模式
|
/// 登录模式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public LoginModeEnum LoginMode { get; set; }
|
public LoginModeEnum LoginMode { get; set; } = LoginModeEnum.PC;
|
||||||
}
|
}
|
||||||
@ -21,13 +21,15 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
private readonly SysCacheService _sysCacheService;
|
private readonly SysCacheService _sysCacheService;
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
private readonly ICaptcha _captcha;
|
private readonly ICaptcha _captcha;
|
||||||
|
private readonly IEventPublisher _eventPublisher;
|
||||||
|
|
||||||
public SysAuthService(UserManager userManager,
|
public SysAuthService(UserManager userManager,
|
||||||
SqlSugarRepository<SysUser> sysUserRep,
|
SqlSugarRepository<SysUser> sysUserRep,
|
||||||
SysConfigService sysConfigService,
|
SysConfigService sysConfigService,
|
||||||
SysCacheService sysCacheService,
|
SysCacheService sysCacheService,
|
||||||
IHttpContextAccessor httpContextAccessor,
|
IHttpContextAccessor httpContextAccessor,
|
||||||
ICaptcha captcha)
|
ICaptcha captcha,
|
||||||
|
IEventPublisher eventPublisher)
|
||||||
{
|
{
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_sysUserRep = sysUserRep;
|
_sysUserRep = sysUserRep;
|
||||||
@ -35,6 +37,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
_sysCacheService = sysCacheService;
|
_sysCacheService = sysCacheService;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
_captcha = captcha;
|
_captcha = captcha;
|
||||||
|
_eventPublisher = eventPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -57,21 +60,18 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
// 判断是否开启验证码并校验
|
// 判断是否开启验证码并校验
|
||||||
if (await _sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysCaptcha) && !_captcha.Validate(input.CodeId.ToString(), input.Code)) throw Oops.Oh(ErrorCodeEnum.D0008);
|
if (await _sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysCaptcha) && !_captcha.Validate(input.CodeId.ToString(), input.Code)) throw Oops.Oh(ErrorCodeEnum.D0008);
|
||||||
|
|
||||||
// 获取登录租户和用户
|
// 获取并验证账号
|
||||||
var (tenant, user) = await GetLoginUserAndTenant(input.TenantId, account: input.Account);
|
var user = await GetLoginUser(input.TenantId, account: input.Account);
|
||||||
|
|
||||||
// 账号是否被冻结
|
|
||||||
if (user.Status == StatusEnum.Disable) throw Oops.Oh(ErrorCodeEnum.D1017);
|
|
||||||
|
|
||||||
// 是否开启域登录验证
|
// 是否开启域登录验证
|
||||||
if (await _sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysDomainLogin))
|
if (await _sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysDomainLogin))
|
||||||
{
|
{
|
||||||
var userLdap = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysUserLdap>>().GetFirstAsync(u => u.UserId == user.Id && u.TenantId == tenant.Id);
|
var userLdap = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysUserLdap>>().GetFirstAsync(u => u.UserId == user.Id && u.TenantId == user.TenantId);
|
||||||
if (userLdap == null)
|
if (userLdap == null)
|
||||||
{
|
{
|
||||||
VerifyPassword(input.Password, keyPasswordErrorTimes, passwordErrorTimes, user);
|
VerifyPassword(input.Password, keyPasswordErrorTimes, passwordErrorTimes, user);
|
||||||
}
|
}
|
||||||
else if (!await App.GetRequiredService<SysLdapService>().AuthAccount(tenant.Id, userLdap.Account, CryptogramUtil.Decrypt(input.Password)))
|
else if (!await App.GetRequiredService<SysLdapService>().AuthAccount(user.TenantId, userLdap.Account, CryptogramUtil.Decrypt(input.Password)))
|
||||||
{
|
{
|
||||||
_sysCacheService.Set(keyPasswordErrorTimes, ++passwordErrorTimes, TimeSpan.FromMinutes(30));
|
_sysCacheService.Set(keyPasswordErrorTimes, ++passwordErrorTimes, TimeSpan.FromMinutes(30));
|
||||||
throw Oops.Oh(ErrorCodeEnum.D1000);
|
throw Oops.Oh(ErrorCodeEnum.D1000);
|
||||||
@ -83,42 +83,42 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
// 登录成功则清空密码错误次数
|
// 登录成功则清空密码错误次数
|
||||||
_sysCacheService.Remove(keyPasswordErrorTimes);
|
_sysCacheService.Remove(keyPasswordErrorTimes);
|
||||||
|
|
||||||
return await CreateToken(user, tenant.AppId, input.LoginMode);
|
return await CreateToken(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取登录租户和用户
|
/// 获取登录用户
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tenantId"></param>
|
/// <param name="tenantId"></param>
|
||||||
/// <param name="account"></param>
|
/// <param name="account"></param>
|
||||||
/// <param name="phone"></param>
|
/// <param name="phone"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public async Task<(SysTenant tenant, SysUser user)> GetLoginUserAndTenant(long tenantId, string account = null, string phone = null)
|
public async Task<SysUser> GetLoginUser(long tenantId, string account = null, string phone = null)
|
||||||
{
|
{
|
||||||
// 若没有传值租户Id,则从请求页URL参数中获取租户Id(空则默认租户)
|
//// 若没有传值租户Id,则从请求页URL参数中获取租户Id(空则默认租户)
|
||||||
if (tenantId < 1)
|
//if (tenantId < 1)
|
||||||
{
|
//{
|
||||||
var tenantidStr = _httpContextAccessor.HttpContext.Request.Query["tenantid"].ToString();
|
// var tenantidStr = _httpContextAccessor.HttpContext.Request.Query["tenantid"].ToString();
|
||||||
tenantId = string.IsNullOrWhiteSpace(tenantidStr) ? SqlSugarConst.DefaultTenantId : long.Parse(tenantidStr);
|
// tenantId = string.IsNullOrWhiteSpace(tenantidStr) ? SqlSugarConst.DefaultTenantId : long.Parse(tenantidStr);
|
||||||
}
|
//}
|
||||||
|
|
||||||
// 判断租户是否存在及状态
|
|
||||||
var tenant = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Id == tenantId);
|
|
||||||
if (tenant?.Status != StatusEnum.Enable) throw Oops.Oh(ErrorCodeEnum.Z1003);
|
|
||||||
|
|
||||||
// 判断账号是否存在
|
// 判断账号是否存在
|
||||||
var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter()
|
var user = await _sysUserRep.AsQueryable().Includes(t => t.SysOrg).ClearFilter()
|
||||||
.Where(u => u.AccountType == AccountTypeEnum.SuperAdmin || u.TenantId == tenantId)
|
//.WhereIF(tenantId > 0, u => u.TenantId == tenantId)
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(account), u => u.Account.Equals(account))
|
.WhereIF(!string.IsNullOrWhiteSpace(account), u => u.Account.Equals(account))
|
||||||
.WhereIF(!string.IsNullOrWhiteSpace(phone), u => u.Phone.Equals(phone))
|
.WhereIF(!string.IsNullOrWhiteSpace(phone), u => u.Phone.Equals(phone))
|
||||||
.FirstAsync();
|
.FirstAsync();
|
||||||
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
_ = user ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||||
|
|
||||||
// 如果是超级管理员,则引用登录选择的租户进入系统
|
// 判断账号是否被冻结
|
||||||
if (user.AccountType == AccountTypeEnum.SuperAdmin) user.TenantId = tenantId;
|
if (user.Status == StatusEnum.Disable) throw Oops.Oh(ErrorCodeEnum.D1017);
|
||||||
|
|
||||||
return (tenant, user);
|
// 判断租户是否存在及状态
|
||||||
|
var tenant = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().GetFirstAsync(u => u.Id == user.TenantId);
|
||||||
|
if (tenant?.Status != StatusEnum.Enable) throw Oops.Oh(ErrorCodeEnum.Z1003);
|
||||||
|
|
||||||
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -200,26 +200,21 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
// 校验短信验证码
|
// 校验短信验证码
|
||||||
App.GetRequiredService<SysSmsService>().VerifyCode(new SmsVerifyCodeInput { Phone = input.Phone, Code = input.Code });
|
App.GetRequiredService<SysSmsService>().VerifyCode(new SmsVerifyCodeInput { Phone = input.Phone, Code = input.Code });
|
||||||
|
|
||||||
// 获取登录租户和用户
|
// 获取并验证账号
|
||||||
var (tenant, user) = await GetLoginUserAndTenant(input.TenantId, phone: input.Phone);
|
var user = await GetLoginUser(input.TenantId, phone: input.Phone);
|
||||||
|
|
||||||
return await CreateToken(user, tenant.AppId, input.LoginMode);
|
return await CreateToken(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 生成Token令牌 🔖
|
/// 生成Token令牌 🔖
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="user"></param>
|
/// <param name="user"></param>
|
||||||
/// <param name="appId"></param>
|
|
||||||
/// <param name="loginMode"></param>
|
/// <param name="loginMode"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
internal async Task<LoginOutput> CreateToken(SysUser user, long? appId, LoginModeEnum loginMode)
|
internal async Task<LoginOutput> CreateToken(SysUser user, LoginModeEnum loginMode = LoginModeEnum.PC)
|
||||||
{
|
{
|
||||||
// 默认PC端登录模式
|
|
||||||
if (loginMode == 0)
|
|
||||||
loginMode = LoginModeEnum.PC;
|
|
||||||
|
|
||||||
// 单用户登录
|
// 单用户登录
|
||||||
await App.GetRequiredService<SysOnlineUserService>().SingleLogin(user.Id, loginMode);
|
await App.GetRequiredService<SysOnlineUserService>().SingleLogin(user.Id, loginMode);
|
||||||
|
|
||||||
@ -227,7 +222,6 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
||||||
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ ClaimConst.AppId, appId },
|
|
||||||
{ ClaimConst.UserId, user.Id },
|
{ ClaimConst.UserId, user.Id },
|
||||||
{ ClaimConst.TenantId, user.TenantId },
|
{ ClaimConst.TenantId, user.TenantId },
|
||||||
{ ClaimConst.Account, user.Account },
|
{ ClaimConst.Account, user.Account },
|
||||||
@ -263,6 +257,9 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
u.LastLoginDevice,
|
u.LastLoginDevice,
|
||||||
}).ExecuteCommandAsync();
|
}).ExecuteCommandAsync();
|
||||||
|
|
||||||
|
// 发布系统登录事件
|
||||||
|
await _eventPublisher.PublishAsync(UserEventTypeEnum.Login, user);
|
||||||
|
|
||||||
return new LoginOutput
|
return new LoginOutput
|
||||||
{
|
{
|
||||||
AccessToken = accessToken,
|
AccessToken = accessToken,
|
||||||
@ -330,11 +327,14 @@ public class SysAuthService : IDynamicApiController, ITransient
|
|||||||
/// 退出系统 🔖
|
/// 退出系统 🔖
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DisplayName("退出系统")]
|
[DisplayName("退出系统")]
|
||||||
public void Logout()
|
public async void Logout()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(_userManager.Account))
|
if (string.IsNullOrWhiteSpace(_userManager.Account))
|
||||||
throw Oops.Oh(ErrorCodeEnum.D1011);
|
throw Oops.Oh(ErrorCodeEnum.D1011);
|
||||||
|
|
||||||
|
// 发布系统退出事件
|
||||||
|
await _eventPublisher.PublishAsync(UserEventTypeEnum.Logout, _userManager);
|
||||||
|
|
||||||
_httpContextAccessor.HttpContext.SignoutToSwagger();
|
_httpContextAccessor.HttpContext.SignoutToSwagger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -112,7 +112,7 @@ public class SysLdapService : IDynamicApiController, ITransient
|
|||||||
/// <param name="tenantId">租户</param>
|
/// <param name="tenantId">租户</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[NonAction]
|
[NonAction]
|
||||||
public async Task<bool> AuthAccount(long tenantId, string account, string password)
|
public async Task<bool> AuthAccount(long? tenantId, string account, string password)
|
||||||
{
|
{
|
||||||
var sysLdap = await _sysLdapRep.GetFirstAsync(u => u.TenantId == tenantId) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
var sysLdap = await _sysLdapRep.GetFirstAsync(u => u.TenantId == tenantId) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
||||||
var ldapConn = new LdapConnection();
|
var ldapConn = new LdapConnection();
|
||||||
|
|||||||
@ -113,7 +113,7 @@ public class SysOAuthService : IDynamicApiController, ITransient
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 构建Token令牌,默认回调登录为PC模式
|
// 构建Token令牌,默认回调登录为PC模式
|
||||||
var token = await App.GetRequiredService<SysAuthService>().CreateToken(wechatUser.SysUser, SqlSugarConst.DefaultAppId, LoginModeEnum.PC);
|
var token = await App.GetRequiredService<SysAuthService>().CreateToken(wechatUser.SysUser);
|
||||||
|
|
||||||
return new RedirectResult($"{redirectUrl}/#/login?token={token.AccessToken}");
|
return new RedirectResult($"{redirectUrl}/#/login?token={token.AccessToken}");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,8 +45,8 @@ public class ExcelHelper
|
|||||||
Task.WhenAll(tasks).GetAwaiter().GetResult();
|
Task.WhenAll(tasks).GetAwaiter().GetResult();
|
||||||
|
|
||||||
// 仅导出错误记录
|
// 仅导出错误记录
|
||||||
var errorList = result.Where(u => !string.IsNullOrWhiteSpace(u.Error));
|
var errorList = result.Where(u => !string.IsNullOrWhiteSpace(u.Error)).ToList();
|
||||||
return ExportData(errorList.Any() ? errorList : []);
|
return ExportData(errorList.Count != 0 ? errorList : []);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"name": "admin.net.pro",
|
"name": "admin.net.pro",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "2.4.33",
|
"version": "2.4.33",
|
||||||
"lastBuildTime": "2025.01.14",
|
"lastBuildTime": "2025.01.15",
|
||||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||||
"author": "zuohuaijun",
|
"author": "zuohuaijun",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@ -39,7 +39,7 @@
|
|||||||
"element-plus": "^2.9.3",
|
"element-plus": "^2.9.3",
|
||||||
"exceljs": "^4.4.0",
|
"exceljs": "^4.4.0",
|
||||||
"ezuikit-js": "^8.1.4",
|
"ezuikit-js": "^8.1.4",
|
||||||
"gcoord": "^1.0.6",
|
"gcoord": "^1.0.7",
|
||||||
"js-cookie": "^3.0.5",
|
"js-cookie": "^3.0.5",
|
||||||
"js-table2excel": "^1.1.2",
|
"js-table2excel": "^1.1.2",
|
||||||
"jsplumb": "^2.15.6",
|
"jsplumb": "^2.15.6",
|
||||||
@ -100,7 +100,7 @@
|
|||||||
"less": "^4.2.1",
|
"less": "^4.2.1",
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"rollup-plugin-visualizer": "^5.14.0",
|
"rollup-plugin-visualizer": "^5.14.0",
|
||||||
"sass": "^1.83.3",
|
"sass": "^1.83.4",
|
||||||
"terser": "^5.37.0",
|
"terser": "^5.37.0",
|
||||||
"typescript": "^5.7.3",
|
"typescript": "^5.7.3",
|
||||||
"vite": "^6.0.7",
|
"vite": "^6.0.7",
|
||||||
|
|||||||
@ -182,7 +182,7 @@ const onHandleCommandClick = (path: string) => {
|
|||||||
showCancelButton: true,
|
showCancelButton: true,
|
||||||
confirmButtonText: t('message.user.logOutConfirm'),
|
confirmButtonText: t('message.user.logOutConfirm'),
|
||||||
cancelButtonText: t('message.user.logOutCancel'),
|
cancelButtonText: t('message.user.logOutCancel'),
|
||||||
buttonSize: 'default',
|
// buttonSize: 'default',
|
||||||
beforeClose: async (action, instance, done) => {
|
beforeClose: async (action, instance, done) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
instance.confirmButtonLoading = true;
|
instance.confirmButtonLoading = true;
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-tabs v-model="activeTab" class="demo-tabs">
|
<el-tabs v-model="activeTab" class="demo-tabs">
|
||||||
<el-tab-pane label="代码生成" name="codeGen" style="height: 600px">
|
<el-tab-pane label="代码生成" name="codeGen" style="height: 700px">
|
||||||
<div style="color: red; padding: 10px 10px; background: #faecd8; margin-bottom: 10px">
|
<div style="color: red; padding: 10px 10px; background: #faecd8; margin-bottom: 10px">
|
||||||
<el-icon style="transform: translateY(2px)"><ele-Bell /></el-icon>
|
<el-icon style="transform: translateY(2px)"><ele-Bell /></el-icon>
|
||||||
<span> 若找不到在前端生成的实体/表,请检查配置文件中实体所在程序集或重启后台服务。 </span>
|
<span> 若找不到在前端生成的实体/表,请检查配置文件中实体所在程序集或重启后台服务。 </span>
|
||||||
@ -73,13 +73,6 @@
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
|
||||||
<el-form-item label="Name字段" prop="treeName" :rules="[{ required: true, message: '请选择树控件Name字段', trigger: 'blur' }]">
|
|
||||||
<el-select v-model="state.ruleForm.treeName" @change="treeNameChanged" value-key="value" filterable clearable class="w100">
|
|
||||||
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="业务名" prop="busName" :rules="[{ required: true, message: '业务名不能为空', trigger: 'blur' }]">
|
<el-form-item label="业务名" prop="busName" :rules="[{ required: true, message: '业务名不能为空', trigger: 'blur' }]">
|
||||||
<el-input v-model="state.ruleForm.busName" placeholder="请输入" clearable />
|
<el-input v-model="state.ruleForm.busName" placeholder="请输入" clearable />
|
||||||
@ -213,21 +206,31 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-col> -->
|
</el-col> -->
|
||||||
<el-col>
|
<el-col>
|
||||||
|
<el-divider content-position="center"> 左边布局显示树形列表;右边布局上下结构显示主子表数据列表 </el-divider>
|
||||||
|
|
||||||
|
<!-- <p><el-tag style="border: 1 solid var(--el-border-color)">以下默认页面左右布局,左边布局显示树形列表,右边布局上下结构显示主子表数据列表</el-tag></p> -->
|
||||||
<el-tabs v-model="activeName" class="demo-tabs">
|
<el-tabs v-model="activeName" class="demo-tabs">
|
||||||
<el-tab-pane label="页面左边树" name="1">
|
<el-tab-pane label="页面左(树列表)" name="1">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="树库定位器" prop="configId2">
|
<el-form-item label="树 - 库定位器" prop="configId2">
|
||||||
<el-select v-model="state.ruleForm.configId2" placeholder="库名" filterable @change="dbChanged2()" class="w100">
|
<el-select v-model="state.ruleForm.configId2" placeholder="库名" filterable @change="dbChanged2()" class="w100">
|
||||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<!-- <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
|
<el-form-item label="Name字段" prop="treeName" :rules="[{ required: true, message: '请选择树控件Name字段', trigger: 'blur' }]">
|
||||||
|
<el-select v-model="state.ruleForm.treeName" @change="treeNameChanged" value-key="value" filterable clearable class="w100">
|
||||||
|
<el-option v-for="item in state.columnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col> -->
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="左边树表" prop="leftTab">
|
<el-form-item label="树表名称">
|
||||||
<template v-slot:label>
|
<template v-slot:label>
|
||||||
<div>
|
<div>
|
||||||
左边树表
|
树表名称
|
||||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@ -240,14 +243,14 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="左边树关联字段" prop="leftKey">
|
<el-form-item label="树关联字段">
|
||||||
<el-select v-model="state.ruleForm.leftKey" @change="leftKeyChanged" value-key="value" filterable clearable class="w100">
|
<el-select v-model="state.ruleForm.leftKey" @change="leftKeyChanged" value-key="value" filterable clearable class="w100">
|
||||||
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="关联主表字段" prop="bottomKey">
|
<el-form-item label="关联主表字段">
|
||||||
<template v-slot:label>
|
<template v-slot:label>
|
||||||
<div>
|
<div>
|
||||||
关联主表字段
|
关联主表字段
|
||||||
@ -263,7 +266,7 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="左边树Name字段" prop="leftName">
|
<el-form-item label="树显示名称">
|
||||||
<el-select v-model="state.ruleForm.leftName" @change="leftNameChanged" value-key="value" filterable clearable class="w100">
|
<el-select v-model="state.ruleForm.leftName" @change="leftNameChanged" value-key="value" filterable clearable class="w100">
|
||||||
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
<el-option v-for="item in state.lcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -271,26 +274,26 @@
|
|||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="模板" prop="template">
|
<el-form-item label="模板">
|
||||||
<el-input v-model="state.ruleForm.template" clearable placeholder="请输入" />
|
<el-input v-model="state.ruleForm.template" clearable placeholder="请输入" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="右区域下框" name="2">
|
<el-tab-pane label="页面右(主子表)" name="2">
|
||||||
<el-row :gutter="10">
|
<el-row :gutter="10">
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="右区域下框库定位器" prop="configId3">
|
<el-form-item label="子表 - 库定位器" prop="configId3">
|
||||||
<el-select v-model="state.ruleForm.configId3" placeholder="库名" filterable @change="dbChanged3()" class="w100">
|
<el-select v-model="state.ruleForm.configId3" placeholder="库名" filterable @change="dbChanged3()" class="w100">
|
||||||
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
<el-option v-for="item in state.dbData" :key="item.configId" :label="item.configId" :value="item.configId" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="下表名称" prop="bottomTab">
|
<el-form-item label="子表名称" prop="bottomTab">
|
||||||
<template v-slot:label>
|
<template v-slot:label>
|
||||||
<div>
|
<div>
|
||||||
下框关联表名称
|
子表名称
|
||||||
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
<el-tooltip raw-content content="若找不到在前端生成的实体/表,同上,如表有下划线_则因实体去掉划线取不到字段。" placement="top">
|
||||||
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"><ele-QuestionFilled /></el-icon>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
@ -302,7 +305,7 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
|
||||||
<el-form-item label="下框表关联字段" prop="bottomKey">
|
<el-form-item label="子表关联字段" prop="bottomKey">
|
||||||
<el-select v-model="state.ruleForm.bottomKey" @change="bottomKeyChanged" value-key="value" filterable clearable class="w100">
|
<el-select v-model="state.ruleForm.bottomKey" @change="bottomKeyChanged" value-key="value" filterable clearable class="w100">
|
||||||
<el-option v-for="item in state.bcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
<el-option v-for="item in state.bcolumnData" :key="item.columnName" :label="item.columnName + ' ( ' + item.columnName + ' ) [' + item.columnComment + ']'" :value="item" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@ -330,7 +333,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane label="选择模板" name="template" style="height: 600px">
|
<el-tab-pane label="选择模板" name="template" style="height: 700px">
|
||||||
<el-table ref="templateTableRef" :data="templateTableData" @selection-change="handleSelectionChange" style="width: 100%">
|
<el-table ref="templateTableRef" :data="templateTableData" @selection-change="handleSelectionChange" style="width: 100%">
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column property="name" label="模板文件名" width="280" />
|
<el-table-column property="name" label="模板文件名" width="280" />
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user