😎去掉租户配置参数相关

This commit is contained in:
zuohuaijun 2025-09-14 10:49:14 +08:00
parent d08a642514
commit 3a76b2a0fc
12 changed files with 201 additions and 553 deletions

View File

@ -21,6 +21,11 @@ public class CacheConst
/// </summary> /// </summary>
public const string KeyTokenBlacklist = "sys_token_blacklist:"; public const string KeyTokenBlacklist = "sys_token_blacklist:";
/// <summary>
/// 所有接口缓存(接口集合)
/// </summary>
public const string KeyAllApi = "sys_all_api";
/// <summary> /// <summary>
/// 用户接口缓存(接口集合) /// 用户接口缓存(接口集合)
/// </summary> /// </summary>

View File

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

View File

@ -1,22 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core;
/// <summary>
/// 系统租户字典值表
/// </summary>
[SugarTable(null, "系统租户字典值表")]
[SysTable]
[SugarIndex("i_{table}_c", nameof(Code), OrderByType.Asc, nameof(TenantId), OrderByType.Asc)]
public partial class SysDictDataTenant : SysDictData, ITenantIdFilter
{
/// <summary>
/// 租户Id
/// </summary>
[SugarColumn(ColumnDescription = "租户Id", IsOnlyIgnoreUpdate = true)]
public virtual long? TenantId { get; set; }
}

View File

@ -54,11 +54,11 @@ public partial class SysDictType : EntityBase
[SugarColumn(ColumnDescription = "是否是内置字典", DefaultValue = "1")] [SugarColumn(ColumnDescription = "是否是内置字典", DefaultValue = "1")]
public virtual YesNoEnum SysFlag { get; set; } = YesNoEnum.Y; public virtual YesNoEnum SysFlag { get; set; } = YesNoEnum.Y;
/// <summary> ///// <summary>
/// 是否是租户字典Y-是N-否) ///// 是否是租户字典Y-是N-否)
/// </summary> ///// </summary>
[SugarColumn(ColumnDescription = "是否是租户字典", DefaultValue = "2")] //[SugarColumn(ColumnDescription = "是否是租户字典", DefaultValue = "2")]
public virtual YesNoEnum IsTenant { get; set; } = YesNoEnum.N; //public virtual YesNoEnum IsTenant { get; set; } = YesNoEnum.N;
/// <summary> /// <summary>
/// 是否是枚举转换字典Y-是N-否) /// 是否是枚举转换字典Y-是N-否)

View File

@ -7,7 +7,7 @@
namespace Admin.NET.Core; namespace Admin.NET.Core;
/// <summary> /// <summary>
/// 系统用户角色 /// 系统用户密码记录
/// </summary> /// </summary>
[SugarTable(null, "系统用户密码记录表")] [SugarTable(null, "系统用户密码记录表")]
[SysTable] [SysTable]

View File

@ -1,132 +1,132 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。 // Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
// //
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。 // 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
// //
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任! // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core; namespace Admin.NET.Core;
/// <summary> /// <summary>
/// 微信退款表 /// 系统微信退款表
/// </summary> /// </summary>
[SugarTable(null, "系统微信退款表")] [SugarTable(null, "系统微信退款表")]
[SysTable] [SysTable]
[SugarIndex("i_{table}_o", nameof(OrderId), OrderByType.Desc)] [SugarIndex("i_{table}_o", nameof(OrderId), OrderByType.Desc)]
public class SysWechatRefund : EntityBase public class SysWechatRefund : EntityBase
{ {
/// <summary> /// <summary>
/// 微信支付订单号(原支付交易对应的微信订单号) /// 微信支付订单号(原支付交易对应的微信订单号)
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "微信支付订单号", Length = 32)] [SugarColumn(ColumnDescription = "微信支付订单号", Length = 32)]
[Required] [Required]
public string TransactionId { get; set; } public string TransactionId { get; set; }
/// <summary> /// <summary>
/// 商户订单号(原交易对应的商户付款单号) /// 商户订单号(原交易对应的商户付款单号)
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "商户付款单号", Length = 32)] [SugarColumn(ColumnDescription = "商户付款单号", Length = 32)]
[Required] [Required]
public string OutTradeNumber { get; set; } public string OutTradeNumber { get; set; }
/// <summary> /// <summary>
/// 商户系统内部的退款单号商户系统内部唯一只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。 /// 商户系统内部的退款单号商户系统内部唯一只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "商户退款单号", Length = 64)] [SugarColumn(ColumnDescription = "商户退款单号", Length = 64)]
[Required] [Required]
public string OutRefundNumber { get; set; } public string OutRefundNumber { get; set; }
/// <summary> /// <summary>
/// 微信接口退款ID /// 微信接口退款ID
/// </summary> /// </summary>
public string RefundId { get; set; } public string RefundId { get; set; }
/// <summary> /// <summary>
/// 退款原因,示例:商品已售完 /// 退款原因,示例:商品已售完
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "退款原因", Length = 80)] [SugarColumn(ColumnDescription = "退款原因", Length = 80)]
public string Reason { get; set; } public string Reason { get; set; }
/// <summary> /// <summary>
/// 退款金额 /// 退款金额
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "退款金额")] [SugarColumn(ColumnDescription = "退款金额")]
public int Refund { get; set; } public int Refund { get; set; }
/// <summary> /// <summary>
/// 原订单总金额 /// 原订单总金额
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "订单总金额")] [SugarColumn(ColumnDescription = "订单总金额")]
public int Total { get; set; } public int Total { get; set; }
/// <summary> /// <summary>
/// 退款结果回调url /// 退款结果回调url
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "退款结果回调url", Length = 256)] [SugarColumn(ColumnDescription = "退款结果回调url", Length = 256)]
public string? NotifyUrl { get; set; } public string? NotifyUrl { get; set; }
/// <summary> /// <summary>
/// 退款资金来源, 可不传,默认使用未结算资金退款(仅对老资金流商户适用) /// 退款资金来源, 可不传,默认使用未结算资金退款(仅对老资金流商户适用)
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "退款资金来源", Length = 32)] [SugarColumn(ColumnDescription = "退款资金来源", Length = 32)]
public string? FundsAccount { get; set; } public string? FundsAccount { get; set; }
/// <summary> /// <summary>
/// 关联的商户订单号 /// 关联的商户订单号
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的用户订单号", Length = 256)] [SugarColumn(ColumnDescription = "关联的用户订单号", Length = 256)]
public string? OrderId { get; set; } public string? OrderId { get; set; }
/// <summary> /// <summary>
/// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款) /// 关联的商户订单状态(或者为第几次支付,有些订单涉及多次支付,比如先付预付款,后补尾款)
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户订单状态", Length = 32)] [SugarColumn(ColumnDescription = "关联的商户订单状态", Length = 32)]
public string? RefundStatus { get; set; } public string? RefundStatus { get; set; }
/// <summary> /// <summary>
/// 支完成时间 /// 支完成时间
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "完成时间")] [SugarColumn(ColumnDescription = "完成时间")]
public DateTime? SuccessTime { get; set; } public DateTime? SuccessTime { get; set; }
/// <summary> /// <summary>
/// 关联的商户商品编码 /// 关联的商户商品编码
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品编码", Length = 32)] [SugarColumn(ColumnDescription = "关联的商户商品编码", Length = 32)]
public string? MerchantGoodsId { get; set; } public string? MerchantGoodsId { get; set; }
/// <summary> /// <summary>
/// 关联的商户商品名称 /// 关联的商户商品名称
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品名称", Length = 256)] [SugarColumn(ColumnDescription = "关联的商户商品名称", Length = 256)]
public string? GoodsName { get; set; } public string? GoodsName { get; set; }
/// <summary> /// <summary>
/// 关联的商户商品单价 /// 关联的商户商品单价
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品单价")] [SugarColumn(ColumnDescription = "关联的商户商品单价")]
public int UnitPrice { get; set; } public int UnitPrice { get; set; }
/// <summary> /// <summary>
/// 关联的商户商品退款金额 /// 关联的商户商品退款金额
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品退款金额")] [SugarColumn(ColumnDescription = "关联的商户商品退款金额")]
public int RefundAmount { get; set; } public int RefundAmount { get; set; }
/// <summary> /// <summary>
/// 关联的商户商品退货数量 /// 关联的商户商品退货数量
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "关联的商户商品退货数量")] [SugarColumn(ColumnDescription = "关联的商户商品退货数量")]
public int RefundQuantity { get; set; } = 1; public int RefundQuantity { get; set; } = 1;
/// <summary> /// <summary>
/// 附加数据 /// 附加数据
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "附加数据")] [SugarColumn(ColumnDescription = "附加数据")]
public string? Attachment { get; set; } public string? Attachment { get; set; }
/// <summary> /// <summary>
/// 备注 /// 备注
/// </summary> /// </summary>
[SugarColumn(ColumnDescription = "备注", ColumnDataType = StaticConfig.CodeFirst_BigString)] [SugarColumn(ColumnDescription = "备注", ColumnDataType = StaticConfig.CodeFirst_BigString)]
public string? Remark { get; set; } public string? Remark { get; set; }
} }

View File

@ -79,89 +79,80 @@ public class SysCommonService : IDynamicApiController, ITransient
/// <summary> /// <summary>
/// 获取所有接口/动态API 🔖 /// 获取所有接口/动态API 🔖
/// </summary> /// </summary>
/// <param name="groupName"></param>
/// <param name="isAppApi"></param>
/// <returns></returns> /// <returns></returns>
[DisplayName("获取所有接口/动态API")] [DisplayName("获取所有接口/动态API")]
public List<ApiOutput> GetApiList([FromQuery] string groupName = "", [FromQuery] bool isAppApi = false) public List<ApiOutput> GetSysAllApiList()
{ {
var apiList = new List<ApiOutput>(); return _sysCacheService.GetOrAdd(CacheConst.KeyAllApi, _ =>
//// 路由前缀
//var defaultRoutePrefix = App.GetOptions<DynamicApiControllerSettingsOptions>().DefaultRoutePrefix;
//var menuIdList = _userManager.SuperAdmin ? new List<long>() : await GetMenuIdList();
// 获取所有接口分组
var apiDescriptionGroups = _apiProvider.ApiDescriptionGroups.Items;
foreach (ApiDescriptionGroup group in apiDescriptionGroups)
{ {
if (!string.IsNullOrWhiteSpace(groupName) && group.GroupName != groupName) var apiList = new List<ApiOutput>();
continue;
var apiOuput = new ApiOutput //// 路由前缀
//var defaultRoutePrefix = App.GetOptions<DynamicApiControllerSettingsOptions>().DefaultRoutePrefix;
// 获取所有接口分组
var apiDescriptionGroups = _apiProvider.ApiDescriptionGroups.Items;
foreach (ApiDescriptionGroup group in apiDescriptionGroups)
{ {
Name = "", //if (!string.IsNullOrWhiteSpace(groupName) && group.GroupName != groupName)
Desc = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName, // continue;
Route = "",
};
// 获取分组的所有接口
var actions = group.Items;
foreach (ApiDescription action in actions)
{
// 路由
var route = action.RelativePath.Contains('{') ? action.RelativePath[..(action.RelativePath.IndexOf('{') - 1)] : action.RelativePath; // 去掉路由参数
route = route[(route.IndexOf('/') + 1)..]; // 去掉路由前缀
// 接口分组/控制器信息 var apiOuput = new ApiOutput
if (action.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor)
continue;
// 是否只获取所有的移动端/AppApi接口
if (isAppApi)
{
var appApiDescription = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<AppApiDescriptionAttribute>(true);
if (appApiDescription == null) continue;
}
var apiDescription = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<ApiDescriptionSettingsAttribute>(true);
var controllerName = controllerActionDescriptor.ControllerName;
var actionName = controllerActionDescriptor.ActionName;
var controllerText = apiDescription?.Description;
if (!apiOuput.Children.Exists(u => u.Name == controllerName))
{
apiOuput.Children.Add(new ApiOutput
{
Name = controllerName,
Desc = string.IsNullOrWhiteSpace(controllerText) ? controllerName : controllerText,
Route = "",
Order = apiDescription?.Order ?? 0,
});
}
// 接口信息
var apiController = apiOuput.Children.FirstOrDefault(u => u.Name.Equals(controllerName));
apiDescription = controllerActionDescriptor.MethodInfo.GetCustomAttribute<ApiDescriptionSettingsAttribute>(true);
var apiText = apiDescription?.Description;
if (string.IsNullOrWhiteSpace(apiText))
apiText = controllerActionDescriptor.MethodInfo.GetCustomAttribute<DisplayNameAttribute>(true)?.DisplayName;
apiController.Children.Add(new ApiOutput
{ {
Name = "", Name = "",
Desc = apiText, Desc = string.IsNullOrWhiteSpace(group.GroupName) ? "系统接口" : group.GroupName,
Route = route, Route = "",
Action = actionName, };
HttpMethod = action.HttpMethod, // 获取分组的所有接口
Order = apiDescription?.Order ?? 0, var actions = group.Items;
}); foreach (ApiDescription action in actions)
{
// 路由
var route = action.RelativePath.Contains('{') ? action.RelativePath[..(action.RelativePath.IndexOf('{') - 1)] : action.RelativePath; // 去掉路由参数
route = route[(route.IndexOf('/') + 1)..]; // 去掉路由前缀
// 接口分组/控制器排序 // 接口分组/控制器信息
apiOuput.Children = [.. apiOuput.Children.OrderByDescending(u => u.Order)]; if (action.ActionDescriptor is not ControllerActionDescriptor controllerActionDescriptor) continue;
var apiDescription = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<ApiDescriptionSettingsAttribute>(true);
var controllerName = controllerActionDescriptor.ControllerName;
var actionName = controllerActionDescriptor.ActionName;
var controllerText = apiDescription?.Description;
if (!apiOuput.Children.Exists(u => u.Name == controllerName))
{
apiOuput.Children.Add(new ApiOutput
{
Name = controllerName,
Desc = string.IsNullOrWhiteSpace(controllerText) ? controllerName : controllerText,
Route = "",
Order = apiDescription?.Order ?? 0,
});
}
// 接口信息
var apiController = apiOuput.Children.FirstOrDefault(u => u.Name.Equals(controllerName));
apiDescription = controllerActionDescriptor.MethodInfo.GetCustomAttribute<ApiDescriptionSettingsAttribute>(true);
var apiText = apiDescription?.Description;
if (string.IsNullOrWhiteSpace(apiText)) apiText = controllerActionDescriptor.MethodInfo.GetCustomAttribute<DisplayNameAttribute>(true)?.DisplayName;
apiController.Children.Add(new ApiOutput
{
Name = "",
Desc = apiText,
Route = route,
Action = actionName,
HttpMethod = action.HttpMethod,
Order = apiDescription?.Order ?? 0,
GroupName = group.GroupName,
IsAppApi = controllerActionDescriptor.ControllerTypeInfo.GetCustomAttribute<AppApiDescriptionAttribute>(true) != null,
});
// 接口分组/控制器排序
apiOuput.Children = [.. apiOuput.Children.OrderByDescending(u => u.Order)];
}
apiList.Add(apiOuput);
} }
return apiList;
apiList.Add(apiOuput); });
}
return apiList;
} }
/// <summary> /// <summary>
@ -171,16 +162,17 @@ public class SysCommonService : IDynamicApiController, ITransient
[DisplayName("获取所有移动端接口")] [DisplayName("获取所有移动端接口")]
public List<string> GetAppApiList() public List<string> GetAppApiList()
{ {
List<string> apiList = []; return _sysCacheService.GetOrAdd(CacheConst.KeyAppApi, _ =>
var queue = new Queue<ApiOutput>(GetApiList());
var item = queue.Dequeue();
while (item != null)
{ {
if (item.Children is { Count: > 0 }) queue.EnqueueRange(item.Children); List<string> appApiList = [];
else apiList.Add(item.Route); var allApiList = GetSysAllApiList();
item = queue.Count > 0 ? queue.Dequeue() : null; foreach (var apiOutput in allApiList)
} {
return apiList; foreach (var controller in apiOutput.Children)
appApiList.AddRange(controller.Children.Where(u => u.IsAppApi).Select(u => u.Route));
}
return appApiList;
});
} }
/// <summary> /// <summary>
@ -195,7 +187,7 @@ public class SysCommonService : IDynamicApiController, ITransient
var defaultRoutePrefix = App.GetOptions<DynamicApiControllerSettingsOptions>().DefaultRoutePrefix; var defaultRoutePrefix = App.GetOptions<DynamicApiControllerSettingsOptions>().DefaultRoutePrefix;
var apiPath = Path.Combine(App.WebHostEnvironment.ContentRootPath, @"App\api"); var apiPath = Path.Combine(App.WebHostEnvironment.ContentRootPath, @"App\api");
var allApiList = GetApiList("", false); // 此处暂时获取全部 var allApiList = GetSysAllApiList();
foreach (var apiOutput in allApiList) foreach (var apiOutput in allApiList)
{ {
foreach (var controller in apiOutput.Children) foreach (var controller in apiOutput.Children)
@ -209,8 +201,9 @@ public class SysCommonService : IDynamicApiController, ITransient
stringBuilder.AppendLine(); stringBuilder.AppendLine();
foreach (var item in controller.Children) foreach (var item in controller.Children)
{ {
var value = item.HttpMethod.Equals("get", StringComparison.CurrentCultureIgnoreCase) ? "params" : "data"; if (!item.IsAppApi) continue;
var value = item.HttpMethod.Equals("get", StringComparison.CurrentCultureIgnoreCase) ? "params" : "data";
stringBuilder.Append($@"// {item.Desc}"); stringBuilder.Append($@"// {item.Desc}");
stringBuilder.AppendLine(); stringBuilder.AppendLine();
stringBuilder.Append($@"export const {item.Action}Api = ({value}) => http.{item.HttpMethod.ToLower()}('/{defaultRoutePrefix}/{item.Route}', {value})"); stringBuilder.Append($@"export const {item.Action}Api = ({value}) => http.{item.HttpMethod.ToLower()}('/{defaultRoutePrefix}/{item.Route}', {value})");
@ -296,8 +289,7 @@ public class SysCommonService : IDynamicApiController, ITransient
public async Task<string> GetNameAbbr(NameAbbrInput input) public async Task<string> GetNameAbbr(NameAbbrInput input)
{ {
if (string.IsNullOrWhiteSpace(input.Text)) return ""; if (string.IsNullOrWhiteSpace(input.Text)) return "";
var map = (await _sysTextAbbrRep.GetListAsync(u => input.Text.Contains(u.Word))) var map = (await _sysTextAbbrRep.GetListAsync(u => input.Text.Contains(u.Word)))?.ToDictionary(u => u.Word, u => u.FullName);
?.ToDictionary(u => u.Word, u => u.FullName);
return map == null || map.Count == 0 ? input.Text : input.Text.Select(c => return map == null || map.Count == 0 ? input.Text : input.Text.Select(c =>
{ {
var val = map.GetValueOrDefault(c.ToString(), c.ToString()); var val = map.GetValueOrDefault(c.ToString(), c.ToString());

View File

@ -1,49 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
public class ConfigTenantInput : BaseIdInput;
public class PageConfigTenantInput : BasePageInput
{
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 编码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 分组编码
/// </summary>
public string GroupCode { get; set; }
}
public class AddConfigTenantInput : SysConfigTenant;
public class UpdateConfigTenantInput : AddConfigTenantInput;
public class DeleteConfigTenantInput : BaseIdInput;
/// <summary>
/// 批量配置参数输入
/// </summary>
public class BatchConfigTenantInput
{
/// <summary>
/// 编码
/// </summary>
public string Code { get; set; }
/// <summary>
/// 属性值
/// </summary>
public string Value { get; set; }
}

View File

@ -1,251 +0,0 @@
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
//
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
//
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
namespace Admin.NET.Core.Service;
/// <summary>
/// 系统租户配置参数服务 🧩
/// </summary>
[ApiDescriptionSettings(Order = 440, Description = "租户配置参数")]
public class SysConfigTenantService : IDynamicApiController, ITransient
{
private readonly SysCacheService _sysCacheService;
private readonly SqlSugarRepository<SysConfigTenant> _sysConfigRep;
public SysConfigTenantService(SysCacheService sysCacheService,
SqlSugarRepository<SysConfigTenant> sysConfigRep)
{
_sysCacheService = sysCacheService;
_sysConfigRep = sysConfigRep;
}
/// <summary>
/// 获取配置参数分页列表 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取配置参数分页列表")]
public async Task<SqlSugarPagedList<SysConfigTenant>> Page(PageConfigTenantInput input)
{
return await _sysConfigRep.AsQueryable()
.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))
.OrderBuilder(input)
.ToPagedListAsync(input.Page, input.PageSize);
}
/// <summary>
/// 获取配置参数列表 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取配置参数列表")]
public async Task<List<SysConfigTenant>> List(PageConfigTenantInput input)
{
return await _sysConfigRep.AsQueryable()
.WhereIF(!string.IsNullOrWhiteSpace(input.GroupCode?.Trim()), u => u.GroupCode.Equals(input.GroupCode))
.ToListAsync();
}
/// <summary>
/// 增加配置参数 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Add"), HttpPost]
[DisplayName("增加配置参数")]
public async Task AddConfig(AddConfigTenantInput input)
{
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<SysConfigTenant>());
}
/// <summary>
/// 更新配置参数 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Update"), HttpPost]
[DisplayName("更新配置参数")]
[UnitOfWork]
public async Task UpdateConfig(UpdateConfigTenantInput input)
{
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);
//// 若修改国密SM2密匙则密码重新加密
//if (input.Code == ConfigConst.SysSM2Key && CryptogramUtil.CryptoType == CryptogramEnum.SM2.ToString())
//{
// var sysUserRep = _sysConfigRep.ChangeRepository<SqlSugarRepository<SysUser>>();
// var sysUsers = await sysUserRep.AsQueryable().Select(u => new { u.Id, u.Password }).ToListAsync();
// foreach(var user in sysUsers)
// {
// user.Password = CryptogramUtil.Encrypt(CryptogramUtil.Decrypt(user.Password));
// }
// await sysUserRep.AsUpdateable(sysUsers).UpdateColumns(u => new { u.Password }).ExecuteCommandAsync();
//}
var config = input.Adapt<SysConfigTenant>();
await _sysConfigRep.AsUpdateable(config).IgnoreColumns(true).ExecuteCommandAsync();
RemoveConfigCache(config);
}
/// <summary>
/// 删除配置参数 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "Delete"), HttpPost]
[DisplayName("删除配置参数")]
public async Task DeleteConfig(DeleteConfigTenantInput input)
{
var config = await _sysConfigRep.GetByIdAsync(input.Id);
// 禁止删除系统参数
if (config.SysFlag == YesNoEnum.Y) throw Oops.Oh(ErrorCodeEnum.D9001);
await _sysConfigRep.DeleteAsync(config);
RemoveConfigCache(config);
}
/// <summary>
/// 批量删除配置参数 🔖
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "BatchDelete"), HttpPost]
[DisplayName("批量删除配置参数")]
public async Task BatchDeleteConfig(List<long> ids)
{
foreach (var id in ids)
{
var config = await _sysConfigRep.GetByIdAsync(id);
// 禁止删除系统参数
if (config.SysFlag == YesNoEnum.Y) continue;
await _sysConfigRep.DeleteAsync(config);
RemoveConfigCache(config);
}
}
/// <summary>
/// 获取配置参数详情 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[DisplayName("获取配置参数详情")]
public async Task<SysConfigTenant> GetDetail([FromQuery] ConfigTenantInput input)
{
return await _sysConfigRep.GetByIdAsync(input.Id);
}
/// <summary>
/// 根据Code获取配置参数
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[NonAction]
public async Task<SysConfigTenant> GetConfig(string code)
{
return await _sysConfigRep.GetFirstAsync(u => u.Code == code);
}
/// <summary>
/// 根据Code获取配置参数值 🔖
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[DisplayName("根据Code获取配置参数值")]
public async Task<string> GetConfigValueByCode(string code)
{
return await GetConfigValueByCode<string>(code);
}
/// <summary>
/// 获取配置参数值
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[NonAction]
public async Task<T> GetConfigValueByCode<T>(string code)
{
if (string.IsNullOrWhiteSpace(code)) return default;
var value = _sysCacheService.Get<string>($"{CacheConst.KeyConfig}{code}");
if (string.IsNullOrEmpty(value))
{
value = (await _sysConfigRep.CopyNew().GetFirstAsync(u => u.Code == code))?.Value;
_sysCacheService.Set($"{CacheConst.KeyConfig}{code}", value);
}
if (string.IsNullOrWhiteSpace(value)) return default;
return (T)Convert.ChangeType(value, typeof(T));
}
/// <summary>
/// 更新配置参数值
/// </summary>
/// <param name="code"></param>
/// <param name="value"></param>
/// <returns></returns>
[NonAction]
public async Task UpdateConfigValue(string code, string value)
{
var config = await _sysConfigRep.GetFirstAsync(u => u.Code == code);
if (config == null) return;
config.Value = value;
await _sysConfigRep.AsUpdateable(config).ExecuteCommandAsync();
RemoveConfigCache(config);
}
/// <summary>
/// 获取分组列表 🔖
/// </summary>
/// <returns></returns>
[DisplayName("获取分组列表")]
public async Task<List<string>> GetGroupList()
{
return await _sysConfigRep.AsQueryable()
.GroupBy(u => u.GroupCode)
.Select(u => u.GroupCode).ToListAsync();
}
/// <summary>
/// 批量更新配置参数值 🔖
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[ApiDescriptionSettings(Name = "BatchUpdate"), HttpPost]
[DisplayName("批量更新配置参数值")]
public async Task BatchUpdateConfig(List<BatchConfigTenantInput> input)
{
foreach (var config in input)
{
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();
RemoveConfigCache(configInfo);
}
}
/// <summary>
/// 清除配置缓存
/// </summary>
/// <param name="config"></param>
private void RemoveConfigCache(SysConfigTenant config)
{
_sysCacheService.Remove($"{CacheConst.KeyConfig}Value:{config.Code}");
_sysCacheService.Remove($"{CacheConst.KeyConfig}Remark:{config.Code}");
_sysCacheService.Remove($"{CacheConst.KeyConfig}{config.GroupCode}:GroupWithCache");
_sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}");
}
}

View File

@ -72,7 +72,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}"); _sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}");
var dictData = dictType.IsTenant == YesNoEnum.Y ? input.Adapt<SysDictDataTenant>() : input.Adapt<SysDictData>(); var dictData = input.Adapt<SysDictData>();
await _sysDictDataRep.Context.Insertable(dictData).ExecuteCommandAsync(); await _sysDictDataRep.Context.Insertable(dictData).ExecuteCommandAsync();
} }
@ -99,7 +99,7 @@ public class SysDictDataService : IDynamicApiController, ITransient
if (dictType.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D3009); if (dictType.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D3009);
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}"); _sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}");
var dictData = dictType.IsTenant == YesNoEnum.Y ? input.Adapt<SysDictDataTenant>() : input.Adapt<SysDictData>(); var dictData = input.Adapt<SysDictData>();
await _sysDictDataRep.Context.Updateable(dictData).ExecuteCommandAsync(); await _sysDictDataRep.Context.Updateable(dictData).ExecuteCommandAsync();
} }
@ -119,8 +119,8 @@ public class SysDictDataService : IDynamicApiController, ITransient
if (dictType.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D3010); if (dictType.SysFlag == YesNoEnum.Y && !_userManager.SuperAdmin) throw Oops.Oh(ErrorCodeEnum.D3010);
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}"); _sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}");
var entity = dictType.IsTenant == YesNoEnum.Y ? input.Adapt<SysDictDataTenant>() : input.Adapt<SysDictData>(); var newDictData = input.Adapt<SysDictData>();
await _sysDictDataRep.Context.Deleteable(entity).ExecuteCommandAsync(); await _sysDictDataRep.Context.Deleteable(newDictData).ExecuteCommandAsync();
} }
/// <summary> /// <summary>
@ -151,8 +151,8 @@ public class SysDictDataService : IDynamicApiController, ITransient
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}"); _sysCacheService.Remove($"{CacheConst.KeyDict}{dictType.Code}");
dictData.Status = input.Status; dictData.Status = input.Status;
var entity = dictType.IsTenant == YesNoEnum.Y ? input.Adapt<SysDictDataTenant>() : input.Adapt<SysDictData>(); var newDictData = input.Adapt<SysDictData>();
await _sysDictDataRep.Context.Updateable(entity).ExecuteCommandAsync(); await _sysDictDataRep.Context.Updateable(newDictData).ExecuteCommandAsync();
} }
/// <summary> /// <summary>
@ -252,9 +252,6 @@ public class SysDictDataService : IDynamicApiController, ITransient
var dictType = await _sysDictDataRep.Change<SysDictType>().AsQueryable().Where(u => u.Id == dictTypeId).FirstAsync(); var dictType = await _sysDictDataRep.Change<SysDictType>().AsQueryable().Where(u => u.Id == dictTypeId).FirstAsync();
_sysCacheService.Remove($"{CacheConst.KeyDict}{dictType?.Code}"); _sysCacheService.Remove($"{CacheConst.KeyDict}{dictType?.Code}");
if (dictType?.IsTenant == YesNoEnum.Y) await _sysDictDataRep.DeleteAsync(u => u.DictTypeId == dictTypeId);
await _sysDictDataRep.Change<SysDictDataTenant>().DeleteAsync(u => u.DictTypeId == dictTypeId);
else
await _sysDictDataRep.DeleteAsync(u => u.DictTypeId == dictTypeId);
} }
} }

View File

@ -36,7 +36,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
public async Task<SqlSugarPagedList<SysDictType>> Page(PageDictTypeInput input) public async Task<SqlSugarPagedList<SysDictType>> Page(PageDictTypeInput input)
{ {
return await _sysDictTypeRep.AsQueryable() return await _sysDictTypeRep.AsQueryable()
.WhereIF(!_userManager.SuperAdmin, u => u.IsTenant == YesNoEnum.Y) //.WhereIF(!_userManager.SuperAdmin, u => u.IsTenant == YesNoEnum.Y)
.WhereIF(!string.IsNullOrEmpty(input.Code?.Trim()), u => u.Code.Contains(input.Code)) .WhereIF(!string.IsNullOrEmpty(input.Code?.Trim()), u => u.Code.Contains(input.Code))
.WhereIF(!string.IsNullOrEmpty(input.Name?.Trim()), u => u.Name.Contains(input.Name)) .WhereIF(!string.IsNullOrEmpty(input.Name?.Trim()), u => u.Name.Contains(input.Name))
.WhereIF(input.SysFlag > 0, u => u.SysFlag == input.SysFlag) .WhereIF(input.SysFlag > 0, u => u.SysFlag == input.SysFlag)
@ -96,7 +96,7 @@ public class SysDictTypeService : IDynamicApiController, ITransient
public async Task UpdateDictType(UpdateDictTypeInput input) public async Task UpdateDictType(UpdateDictTypeInput input)
{ {
var dict = await _sysDictTypeRep.GetFirstAsync(x => x.Id == input.Id); var dict = await _sysDictTypeRep.GetFirstAsync(x => x.Id == input.Id);
if (dict.IsTenant != input.IsTenant) throw Oops.Oh(ErrorCodeEnum.D3012); //if (dict.IsTenant != input.IsTenant) throw Oops.Oh(ErrorCodeEnum.D3012);
if (dict == null) throw Oops.Oh(ErrorCodeEnum.D3000); if (dict == null) throw Oops.Oh(ErrorCodeEnum.D3000);
if (dict.Code.ToLower().EndsWith("enum") && input.Code != dict.Code) throw Oops.Oh(ErrorCodeEnum.D3007); if (dict.Code.ToLower().EndsWith("enum") && input.Code != dict.Code) throw Oops.Oh(ErrorCodeEnum.D3007);

View File

@ -117,8 +117,7 @@ namespace Admin.NET.Web.Core
private static async Task<bool> CheckAuthorizeAsync(DefaultHttpContext httpContext) private static async Task<bool> CheckAuthorizeAsync(DefaultHttpContext httpContext)
{ {
// 排除超管权限判断 // 排除超管权限判断
if (App.User.FindFirst(ClaimConst.AccountType)?.Value == ((int)AccountTypeEnum.SuperAdmin).ToString()) if (App.User.FindFirst(ClaimConst.AccountType)?.Value == ((int)AccountTypeEnum.SuperAdmin).ToString()) return true;
return true;
var serviceScope = httpContext.RequestServices.CreateScope(); var serviceScope = httpContext.RequestServices.CreateScope();