😎1、添加字典缓存;2、添加字典值合法性校验属性
This commit is contained in:
parent
e24efb3970
commit
b9d762f97f
75
Admin.NET/Admin.NET.Core/Attribute/DictAttribute.cs
Normal file
75
Admin.NET/Admin.NET.Core/Attribute/DictAttribute.cs
Normal file
@ -0,0 +1,75 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 字典值合规性校验特性
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true, Inherited = true)]
|
||||
public class DictAttribute : ValidationAttribute, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 字典值合规性校验特性
|
||||
/// </summary>
|
||||
/// <param name="dictTypeCode"></param>
|
||||
/// <param name="errorMessage"></param>
|
||||
public DictAttribute(string dictTypeCode, string errorMessage = "字典值不合法!")
|
||||
{
|
||||
DictTypeCode = dictTypeCode;
|
||||
ErrorMessage = errorMessage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字典值合规性校验
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="validationContext"></param>
|
||||
/// <returns></returns>
|
||||
protected override ValidationResult IsValid(object? value, ValidationContext validationContext)
|
||||
{
|
||||
var valueAsString = value?.ToString();
|
||||
|
||||
// 判断是否允许空值
|
||||
if (AllowNullValue && value == null) return ValidationResult.Success;
|
||||
|
||||
// 是否忽略空字符串
|
||||
if (AllowEmptyStrings && string.IsNullOrEmpty(valueAsString)) return ValidationResult.Success;
|
||||
|
||||
// 查询缓存中是否存在
|
||||
var cacheServiceProvider = validationContext.GetRequiredService<SysCacheService>();
|
||||
var sysDictDataServiceProvider = validationContext.GetRequiredService<SysDictDataService>();
|
||||
|
||||
string cacheKey = $"{CacheConst.KeyDict}{DictTypeCode}";
|
||||
var dictDataList = cacheServiceProvider.Get<HashSet<SysDictData>>(cacheKey);
|
||||
if (dictDataList == null)
|
||||
{
|
||||
dictDataList = sysDictDataServiceProvider.GetDataList(DictTypeCode).Result.ToHashSet();
|
||||
cacheServiceProvider.Set(cacheKey, dictDataList);
|
||||
}
|
||||
|
||||
if (!dictDataList.Select(u => u.Code).ToHashSet().Contains(valueAsString))
|
||||
return new ValidationResult($"提示:{ErrorMessage}|字典【{DictTypeCode}】不包含【{valueAsString}】!");
|
||||
else
|
||||
return ValidationResult.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字典编码
|
||||
/// </summary>
|
||||
public string DictTypeCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否允许空字符串
|
||||
/// </summary>
|
||||
public bool AllowEmptyStrings { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 允许空值,有值才验证,默认 false
|
||||
/// </summary>
|
||||
public bool AllowNullValue { get; set; } = false;
|
||||
}
|
||||
@ -95,4 +95,9 @@ public class CacheConst
|
||||
/// 系统配置缓存
|
||||
/// </summary>
|
||||
public const string KeyConfig = "sys_config:";
|
||||
|
||||
/// <summary>
|
||||
/// 系统字典缓存
|
||||
/// </summary>
|
||||
public const string KeyDict = "sys_dict:";
|
||||
}
|
||||
@ -47,7 +47,7 @@ public partial class SysOrg : EntityTenant
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "机构类型", Length = 64)]
|
||||
[MaxLength(64)]
|
||||
public string? Type { get; set; }
|
||||
public virtual string? Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 负责人Id
|
||||
|
||||
@ -13,11 +13,13 @@ namespace Admin.NET.Core.Service;
|
||||
[AllowAnonymous]
|
||||
public class SysDictDataService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly SysCacheService _sysCacheService;
|
||||
private readonly SqlSugarRepository<SysDictData> _sysDictDataRep;
|
||||
|
||||
public SysDictDataService(SqlSugarRepository<SysDictData> sysDictDataRep)
|
||||
public SysDictDataService(SqlSugarRepository<SysDictData> sysDictDataRep, SysCacheService sysCacheService)
|
||||
{
|
||||
_sysDictDataRep = sysDictDataRep;
|
||||
_sysCacheService = sysCacheService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -40,6 +42,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
/// 获取字典值列表 🔖
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[DisplayName("获取字典值列表")]
|
||||
public async Task<List<SysDictData>> GetList([FromQuery] GetDataDictDataInput input)
|
||||
{
|
||||
@ -67,6 +70,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[ApiDescriptionSettings(Name = "Update"), HttpPost]
|
||||
[DisplayName("更新字典值")]
|
||||
public async Task UpdateDictData(UpdateDictDataInput input)
|
||||
@ -77,6 +81,9 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
isExist = await _sysDictDataRep.IsAnyAsync(u => u.Code == input.Code && u.DictTypeId == input.DictTypeId && u.Id != input.Id);
|
||||
if (isExist) throw Oops.Oh(ErrorCodeEnum.D3003);
|
||||
|
||||
var dictTypeCode = await _sysDictDataRep.AsQueryable().Where(u => u.DictTypeId == input.DictTypeId).Select(u => u.DictType.Code).FirstAsync();
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictTypeCode}");
|
||||
|
||||
await _sysDictDataRep.UpdateAsync(input.Adapt<SysDictData>());
|
||||
}
|
||||
|
||||
@ -85,6 +92,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
|
||||
[DisplayName("删除字典值")]
|
||||
public async Task DeleteDictData(DeleteDictDataInput input)
|
||||
@ -93,6 +101,9 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
if (dictData == null)
|
||||
throw Oops.Oh(ErrorCodeEnum.D3004);
|
||||
|
||||
var dictTypeCode = await _sysDictDataRep.AsQueryable().Where(u => u.DictTypeId == dictData.Id).Select(u => u.DictType.Code).FirstAsync();
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictTypeCode}");
|
||||
|
||||
await _sysDictDataRep.DeleteAsync(dictData);
|
||||
}
|
||||
|
||||
@ -112,6 +123,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[DisplayName("修改字典值状态")]
|
||||
public async Task SetStatus(DictDataInput input)
|
||||
{
|
||||
@ -122,6 +134,9 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
|
||||
throw Oops.Oh(ErrorCodeEnum.D3005);
|
||||
|
||||
var dictTypeCode = await _sysDictDataRep.AsQueryable().Where(u => u.DictTypeId == dictData.Id).Select(u => u.DictType.Code).FirstAsync();
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictTypeCode}");
|
||||
|
||||
dictData.Status = input.Status;
|
||||
await _sysDictDataRep.UpdateAsync(dictData);
|
||||
}
|
||||
@ -134,10 +149,20 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
[NonAction]
|
||||
public async Task<List<SysDictData>> GetDictDataListByDictTypeId(long dictTypeId)
|
||||
{
|
||||
return await _sysDictDataRep.AsQueryable()
|
||||
.Where(u => u.DictTypeId == dictTypeId)
|
||||
.OrderBy(u => new { u.OrderNo, u.Code })
|
||||
.ToListAsync();
|
||||
var dictType = await _sysDictDataRep.GetByIdAsync(dictTypeId);
|
||||
var dictDataList = _sysCacheService.Get<List<SysDictData>>($"{CacheConst.KeyDict}{dictTypeId}");
|
||||
|
||||
if (dictDataList == null)
|
||||
{
|
||||
dictDataList = await _sysDictDataRep.AsQueryable()
|
||||
.Where(u => u.DictTypeId == dictTypeId)
|
||||
.OrderBy(u => new { u.OrderNo, u.Code })
|
||||
.ToListAsync();
|
||||
|
||||
_sysCacheService.Set($"{CacheConst.KeyDict}{dictType.Code}", dictDataList);
|
||||
}
|
||||
|
||||
return dictDataList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -179,6 +204,9 @@ public class SysDictDataService : IDynamicApiController, ITransient
|
||||
[NonAction]
|
||||
public async Task DeleteDictData(long dictTypeId)
|
||||
{
|
||||
var dictTypeCode = await _sysDictDataRep.AsQueryable().Where(u => u.DictTypeId == dictTypeId).Select(u => u.DictType.Code).FirstAsync();
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictTypeCode}");
|
||||
|
||||
await _sysDictDataRep.DeleteAsync(u => u.DictTypeId == dictTypeId);
|
||||
}
|
||||
}
|
||||
@ -15,12 +15,15 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly SqlSugarRepository<SysDictType> _sysDictTypeRep;
|
||||
private readonly SysDictDataService _sysDictDataService;
|
||||
private readonly SysCacheService _sysCacheService;
|
||||
|
||||
public SysDictTypeService(SqlSugarRepository<SysDictType> sysDictTypeRep,
|
||||
SysDictDataService sysDictDataService)
|
||||
SysDictDataService sysDictDataService,
|
||||
SysCacheService sysCacheService)
|
||||
{
|
||||
_sysDictTypeRep = sysDictTypeRep;
|
||||
_sysDictDataService = sysDictDataService;
|
||||
_sysCacheService = sysCacheService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -52,6 +55,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[AllowAnonymous]
|
||||
[DisplayName("获取字典类型-值列表")]
|
||||
public async Task<List<SysDictData>> GetDataList([FromQuery] GetDataDictTypeInput input)
|
||||
@ -84,6 +88,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[ApiDescriptionSettings(Name = "Update"), HttpPost]
|
||||
[DisplayName("更新字典类型")]
|
||||
public async Task UpdateDictType(UpdateDictTypeInput input)
|
||||
@ -96,6 +101,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
if (isExist)
|
||||
throw Oops.Oh(ErrorCodeEnum.D3001);
|
||||
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{input.Code}");
|
||||
await _sysDictTypeRep.UpdateAsync(input.Adapt<SysDictType>());
|
||||
}
|
||||
|
||||
@ -104,6 +110,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
|
||||
[DisplayName("删除字典类型")]
|
||||
public async Task DeleteDictType(DeleteDictTypeInput input)
|
||||
@ -133,6 +140,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[DisplayName("修改字典类型状态")]
|
||||
public async Task SetStatus(DictTypeInput input)
|
||||
{
|
||||
@ -143,6 +151,8 @@ public class SysDictTypeService : IDynamicApiController, ITransient
|
||||
if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
|
||||
throw Oops.Oh(ErrorCodeEnum.D3005);
|
||||
|
||||
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}");
|
||||
|
||||
dictType.Status = input.Status;
|
||||
await _sysDictTypeRep.UpdateAsync(dictType);
|
||||
}
|
||||
|
||||
@ -31,6 +31,12 @@ public class AddOrgInput : SysOrg
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "机构名称不能为空")]
|
||||
public override string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 机构类型
|
||||
/// </summary>
|
||||
[Dict("org_type", ErrorMessage = "机构类型不能合法", AllowNullValue = true, AllowEmptyStrings = true)]
|
||||
public override string? Type { get; set; }
|
||||
}
|
||||
|
||||
public class UpdateOrgInput : AddOrgInput
|
||||
|
||||
@ -14,6 +14,7 @@ public class UserInput : BaseIdInput
|
||||
/// <summary>
|
||||
/// 状态
|
||||
/// </summary>
|
||||
[Dict("StatusEnum")]
|
||||
public StatusEnum Status { get; set; }
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user