feat: 😀实现系统配置参数值租户隔离

This commit is contained in:
喵你个旺呀 2025-01-15 07:04:33 +08:00
parent cbaf030f6f
commit 44e2248613
4 changed files with 126 additions and 12 deletions

View File

@ -32,7 +32,7 @@ public partial class SysConfig : EntityBase
/// <summary>
/// 属性值
/// </summary>
[SugarColumn(ColumnDescription = "属性值", Length = 256)]
[SugarColumn(ColumnDescription = "属性值", Length = 512)]
[MaxLength(256)]
public string? Value { get; set; }

View File

@ -0,0 +1,35 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统配置参数值表
/// </summary>
[SugarTable(null, "系统配置参数值表")]
[SysTable]
[SugarIndex("index_{table}_N", nameof(ConfigId), OrderByType.Asc)]
public partial class SysConfigValue : EntityTenant
{
/// <summary>
/// 配置Id
/// </summary>
[SugarColumn(ColumnDescription = "配置Id")]
public long ConfigId { get; set; }
/// <summary>
/// 属性默认值
/// </summary>
[MaxLength(64)]
[SugarColumn(ColumnDescription = "属性默认值", Length = 512)]
public string? Value { get; set; }
/// <summary>
/// 配置
/// </summary>
[Navigate(NavigateType.OneToOne, nameof(ConfigId))]
public SysConfig Config { get; set; }
}

View File

@ -541,6 +541,12 @@ public enum ErrorCodeEnum
[ErrorCodeItemMetadata("禁止删除系统参数")]
D9001,
/// <summary>
/// 禁止越权操作系统内置参数
/// </summary>
[ErrorCodeItemMetadata("禁止越权操作系统内置参数")]
D9002,
/// <summary>
/// 已存在同名任务调度
/// </summary>

View File

@ -12,14 +12,21 @@ namespace Admin.NET.Core.Service;
[ApiDescriptionSettings(Order = 440, Description = "参数配置")]
public class SysConfigService : IDynamicApiController, ITransient
{
private readonly UserManager _userManager;
private readonly SysCacheService _sysCacheService;
private readonly SqlSugarRepository<SysConfig> _sysConfigRep;
private readonly SqlSugarRepository<SysConfigValue> _sysConfigValueRep;
public SysConfigService(SysCacheService sysCacheService,
public SysConfigService(
UserManager userManager,
SysCacheService sysCacheService,
SqlSugarRepository<SysConfigValue> sysConfigValueRep,
SqlSugarRepository<SysConfig> sysConfigRep)
{
_sysConfigValueRep = sysConfigValueRep;
_sysCacheService = sysCacheService;
_sysConfigRep = sysConfigRep;
_userManager = userManager;
}
/// <summary>
@ -30,7 +37,9 @@ public class SysConfigService : IDynamicApiController, ITransient
[DisplayName("获取参数配置分页列表")]
public async Task<SqlSugarPagedList<SysConfig>> Page(PageConfigInput input)
{
return await _sysConfigRep.AsQueryable()
var query = await GetConfigQueryable();
return await query
.WhereIF(!_userManager.SuperAdmin, u => u.SysFlag == YesNoEnum.N)
.Where(u => u.GroupCode != ConfigConst.SysWebConfigGroup || u.GroupCode == null) // 不显示 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))
@ -46,7 +55,8 @@ public class SysConfigService : IDynamicApiController, ITransient
[DisplayName("获取参数配置列表")]
public async Task<List<SysConfig>> List(PageConfigInput input)
{
return await _sysConfigRep.AsQueryable()
var query = await GetConfigQueryable();
return await query
.WhereIF(!string.IsNullOrWhiteSpace(input.GroupCode?.Trim()), u => u.GroupCode.Equals(input.GroupCode))
.ToListAsync();
}
@ -60,9 +70,9 @@ public class SysConfigService : IDynamicApiController, ITransient
[DisplayName("增加参数配置")]
public async Task AddConfig(AddConfigInput input)
{
if (input.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D9002);
var isExist = await _sysConfigRep.IsAnyAsync(u => u.Name == input.Name || u.Code == input.Code);
if (isExist) throw Oops.Oh(ErrorCodeEnum.D9000);
await _sysConfigRep.InsertAsync(input.Adapt<SysConfig>());
}
@ -76,6 +86,7 @@ public class SysConfigService : IDynamicApiController, ITransient
[UnitOfWork]
public async Task UpdateConfig(UpdateConfigInput input)
{
if (input.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D9002);
var isExist = await _sysConfigRep.IsAnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id);
if (isExist) throw Oops.Oh(ErrorCodeEnum.D9000);
@ -92,7 +103,31 @@ public class SysConfigService : IDynamicApiController, ITransient
//}
var config = input.Adapt<SysConfig>();
await _sysConfigRep.AsUpdateable(config).IgnoreColumns(true).ExecuteCommandAsync();
if (input.SysFlag != YesNoEnum.Y)
{
config.Value = null;
var tenantId = _userManager.TenantId;
if (tenantId <= 0) tenantId = SqlSugarConst.DefaultTenantId;
var configValue = await _sysConfigValueRep.AsQueryable().ClearFilter().Where(u => u.TenantId == tenantId).SingleAsync(u => u.ConfigId == config.Id);
if (configValue == null)
{
await _sysConfigValueRep.InsertAsync(new SysConfigValue()
{
ConfigId = config.Id,
Value = config.Value
});
}
else
{
configValue.Value = config.Value;
await _sysConfigValueRep.UpdateAsync(configValue);
}
}
else
{
await _sysConfigValueRep.DeleteAsync(u => u.ConfigId == config.Id);
}
await _sysConfigRep.AsUpdateable(config).ExecuteCommandAsync();
RemoveConfigCache(config);
}
@ -111,6 +146,7 @@ public class SysConfigService : IDynamicApiController, ITransient
if (config.SysFlag == YesNoEnum.Y) throw Oops.Oh(ErrorCodeEnum.D9001);
await _sysConfigRep.DeleteAsync(config);
await _sysConfigValueRep.DeleteAsync(u => u.ConfigId == config.Id);
RemoveConfigCache(config);
}
@ -131,6 +167,7 @@ public class SysConfigService : IDynamicApiController, ITransient
if (config.SysFlag == YesNoEnum.Y) continue;
await _sysConfigRep.DeleteAsync(config);
await _sysConfigValueRep.DeleteAsync(u => u.ConfigId == id);
RemoveConfigCache(config);
}
@ -155,7 +192,8 @@ public class SysConfigService : IDynamicApiController, ITransient
[NonAction]
public async Task<SysConfig> GetConfig(string code)
{
return await _sysConfigRep.GetFirstAsync(u => u.Code == code);
var query = await GetConfigQueryable();
return await query.FirstAsync(u => u.Code == code);
}
/// <summary>
@ -182,8 +220,9 @@ public class SysConfigService : IDynamicApiController, ITransient
var value = _sysCacheService.Get<string>($"{CacheConst.KeyConfig}{code}");
if (string.IsNullOrEmpty(value))
{
var config = await _sysConfigRep.CopyNew().GetFirstAsync(u => u.Code == code);
value = config != null ? config.Value : default;
var query = await GetConfigQueryable();
var config = await query.FirstAsync(u => u.Code == code);
value = config?.Value;
_sysCacheService.Set($"{CacheConst.KeyConfig}{code}", value);
}
if (string.IsNullOrWhiteSpace(value)) return default;
@ -203,7 +242,7 @@ public class SysConfigService : IDynamicApiController, ITransient
if (config == null) return;
config.Value = value;
await _sysConfigRep.AsUpdateable(config).ExecuteCommandAsync();
await UpdateConfig(config.Adapt<UpdateConfigInput>());
RemoveConfigCache(config);
}
@ -215,7 +254,8 @@ public class SysConfigService : IDynamicApiController, ITransient
[DisplayName("获取分组列表")]
public async Task<List<string>> GetGroupList()
{
return await _sysConfigRep.AsQueryable()
var query = await GetConfigQueryable();
return await query
.Where(u => u.GroupCode != ConfigConst.SysWebConfigGroup || u.GroupCode == null) // 不显示 WebConfig 分组
.GroupBy(u => u.GroupCode)
.Select(u => u.GroupCode).ToListAsync();
@ -259,11 +299,44 @@ public class SysConfigService : IDynamicApiController, ITransient
var configInfo = await _sysConfigRep.GetFirstAsync(u => u.Code == config.Code);
if (configInfo == null) continue;
await _sysConfigRep.AsUpdateable().SetColumns(u => u.Value == config.Value).Where(u => u.Code == config.Code).ExecuteCommandAsync();
configInfo.Value = config.Value;
await UpdateConfig(configInfo.Adapt<UpdateConfigInput>());
RemoveConfigCache(configInfo);
}
}
/// <summary>
/// 获取参数配置查询器
/// </summary>
/// <returns></returns>
[NonAction]
public Task<ISugarQueryable<SysConfig>> GetConfigQueryable()
{
var tenantId = _userManager.TenantId;
if (_userManager.TenantId <= 0) tenantId = SqlSugarConst.DefaultTenantId;
return Task.FromResult(
_sysConfigRep.AsQueryable()
.LeftJoin<SysConfigValue>((u, w) => u.Id == w.ConfigId).ClearFilter()
.Where((u, w) => w.TenantId == null || w.TenantId == tenantId)
.Select((u, w) => new SysConfig
{
Id = u.Id,
Name = u.Name,
Code = u.Code,
GroupCode = u.GroupCode,
SysFlag = u.SysFlag,
Remark = u.Remark,
Value = w.Value ?? u.Value,
CreateTime = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.CreateTime, w.CreateTime),
UpdateTime = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.UpdateTime, w.UpdateTime),
CreateUserId = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.CreateUserId, w.CreateUserId),
CreateUserName = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.CreateUserName, w.CreateUserName),
UpdateUserId = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.UpdateUserId, w.UpdateUserId),
UpdateUserName = SqlFunc.IIF(u.SysFlag == YesNoEnum.Y, u.UpdateUserName, w.UpdateUserName),
})
);
}
/// <summary>
/// 清除配置缓存
/// </summary>