feat: resolve createBy/updateBy to RBAC user display names
Add OmsRbacUserDisplayNameResolver and use it in customer, order, warehouse, and channel APIs so audit fields return names instead of mapIds. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
e875f0c012
commit
07fc7fffe7
@ -102,8 +102,18 @@ public class CustomerPaginatedOutput
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime CreateTime { get; set; }
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建人(展示名称)。
|
||||||
|
/// </summary>
|
||||||
|
public string? CreateBy { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 更新时间。
|
/// 更新时间。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? UpdateTime { get; set; }
|
public DateTime? UpdateTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 更新人(展示名称)。
|
||||||
|
/// </summary>
|
||||||
|
public string? UpdateBy { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,6 +74,9 @@ public partial class SalesProductService
|
|||||||
.GroupBy(x => x.PriceId)
|
.GroupBy(x => x.PriceId)
|
||||||
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList());
|
.ToDictionary(x => x.Key, x => x.OrderBy(item => item.Id).ToList());
|
||||||
|
|
||||||
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
prices.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
|
||||||
|
|
||||||
return prices.Select(price => new SalesProductPriceListOutput
|
return prices.Select(price => new SalesProductPriceListOutput
|
||||||
{
|
{
|
||||||
Id = price.Id,
|
Id = price.Id,
|
||||||
@ -88,9 +91,9 @@ public partial class SalesProductService
|
|||||||
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
Factors = factorMap.TryGetValue(price.Id, out var factors) ? factors.Select(MapPriceFactorOutput).ToList() : [],
|
||||||
Details = detailMap.TryGetValue(price.Id, out var details) ? details.Select(MapPriceDetailOutput).ToList() : [],
|
Details = detailMap.TryGetValue(price.Id, out var details) ? details.Select(MapPriceDetailOutput).ToList() : [],
|
||||||
CreateTime = price.CreateTime,
|
CreateTime = price.CreateTime,
|
||||||
CreateBy = price.CreateUserId <= 0 ? null : price.CreateUserId.ToString(),
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.CreateUserId, auditUserNameMap),
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime),
|
UpdateTime = OmsDocHelper.NullIfDefault(price.UpdateTime),
|
||||||
UpdateBy = price.UpdateUserId <= 0 ? null : price.UpdateUserId.ToString()
|
UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(price.UpdateUserId, auditUserNameMap)
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,7 +345,9 @@ public partial class SalesProductService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SalesProductDetailOutput MapDetailOutput(SalesProduct entity)
|
private static SalesProductDetailOutput MapDetailOutput(
|
||||||
|
SalesProduct entity,
|
||||||
|
IReadOnlyDictionary<int, string> auditUserNameMap)
|
||||||
{
|
{
|
||||||
return new SalesProductDetailOutput
|
return new SalesProductDetailOutput
|
||||||
{
|
{
|
||||||
@ -363,9 +368,9 @@ public partial class SalesProductService
|
|||||||
IsActive = (byte)entity.IsActive,
|
IsActive = (byte)entity.IsActive,
|
||||||
Scheme = entity.Scheme,
|
Scheme = entity.Scheme,
|
||||||
CreateTime = entity.CreateTime,
|
CreateTime = entity.CreateTime,
|
||||||
CreateBy = entity.CreateUserId <= 0 ? null : entity.CreateUserId.ToString(),
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap),
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime),
|
UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime),
|
||||||
UpdateBy = entity.UpdateUserId <= 0 ? null : entity.UpdateUserId.ToString()
|
UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,6 +25,8 @@ public partial class SalesProductService : ApplicationService
|
|||||||
private IWeightRoundingRepository WeightRoundingRepository => LazyServiceProvider.GetRequiredService<IWeightRoundingRepository>();
|
private IWeightRoundingRepository WeightRoundingRepository => LazyServiceProvider.GetRequiredService<IWeightRoundingRepository>();
|
||||||
private AllocationProviderSnapshotEnricher AllocationProviderSnapshotEnricher =>
|
private AllocationProviderSnapshotEnricher AllocationProviderSnapshotEnricher =>
|
||||||
LazyServiceProvider.GetRequiredService<AllocationProviderSnapshotEnricher>();
|
LazyServiceProvider.GetRequiredService<AllocationProviderSnapshotEnricher>();
|
||||||
|
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
|
||||||
|
LazyServiceProvider.GetRequiredService<OmsRbacUserDisplayNameResolver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询销售产品列表。
|
/// 查询销售产品列表。
|
||||||
@ -71,7 +73,9 @@ public partial class SalesProductService : ApplicationService
|
|||||||
public async Task<SalesProductDetailOutput> GetDetailAsync([FromQuery] int id)
|
public async Task<SalesProductDetailOutput> GetDetailAsync([FromQuery] int id)
|
||||||
{
|
{
|
||||||
var entity = await GetProductOrThrowAsync(id);
|
var entity = await GetProductOrThrowAsync(id);
|
||||||
return MapDetailOutput(entity);
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
[entity.CreateUserId, entity.UpdateUserId]);
|
||||||
|
return MapDetailOutput(entity, auditUserNameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -329,7 +329,10 @@ public partial class ServiceChannelService
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ServiceChannelDetailOutput MapDetailOutput(ServiceChannel entity, IReadOnlyDictionary<int, string> groupMap)
|
private static ServiceChannelDetailOutput MapDetailOutput(
|
||||||
|
ServiceChannel entity,
|
||||||
|
IReadOnlyDictionary<int, string> groupMap,
|
||||||
|
IReadOnlyDictionary<int, string> auditUserNameMap)
|
||||||
{
|
{
|
||||||
return new ServiceChannelDetailOutput
|
return new ServiceChannelDetailOutput
|
||||||
{
|
{
|
||||||
@ -346,9 +349,9 @@ public partial class ServiceChannelService
|
|||||||
PreScript = entity.PreScript,
|
PreScript = entity.PreScript,
|
||||||
IsActive = (byte)entity.IsActive,
|
IsActive = (byte)entity.IsActive,
|
||||||
CreateTime = entity.CreateTime,
|
CreateTime = entity.CreateTime,
|
||||||
CreateBy = entity.CreateUserId <= 0 ? null : entity.CreateUserId.ToString(),
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap),
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime),
|
UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime),
|
||||||
UpdateBy = entity.UpdateUserId <= 0 ? null : entity.UpdateUserId.ToString()
|
UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,8 @@ public partial class ServiceChannelService : ApplicationService
|
|||||||
|
|
||||||
private IServiceChannelRepository ServiceChannelRepository => LazyServiceProvider.GetRequiredService<IServiceChannelRepository>();
|
private IServiceChannelRepository ServiceChannelRepository => LazyServiceProvider.GetRequiredService<IServiceChannelRepository>();
|
||||||
private IServiceChannelGroupRepository ServiceChannelGroupRepository => LazyServiceProvider.GetRequiredService<IServiceChannelGroupRepository>();
|
private IServiceChannelGroupRepository ServiceChannelGroupRepository => LazyServiceProvider.GetRequiredService<IServiceChannelGroupRepository>();
|
||||||
|
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
|
||||||
|
LazyServiceProvider.GetRequiredService<OmsRbacUserDisplayNameResolver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询服务渠道列表。
|
/// 查询服务渠道列表。
|
||||||
@ -67,7 +69,9 @@ public partial class ServiceChannelService : ApplicationService
|
|||||||
public async Task<ServiceChannelDetailOutput> GetDetailAsync([FromQuery] int id)
|
public async Task<ServiceChannelDetailOutput> GetDetailAsync([FromQuery] int id)
|
||||||
{
|
{
|
||||||
var entity = await GetEntityOrThrowAsync(id);
|
var entity = await GetEntityOrThrowAsync(id);
|
||||||
return MapDetailOutput(entity, await GetGroupMapAsync());
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
[entity.CreateUserId, entity.UpdateUserId]);
|
||||||
|
return MapDetailOutput(entity, await GetGroupMapAsync(), auditUserNameMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -32,6 +32,9 @@ public class CustomerService : ApplicationService
|
|||||||
|
|
||||||
private FakeRbacDbContext RbacDbContext => LazyServiceProvider.GetRequiredService<FakeRbacDbContext>();
|
private FakeRbacDbContext RbacDbContext => LazyServiceProvider.GetRequiredService<FakeRbacDbContext>();
|
||||||
|
|
||||||
|
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
|
||||||
|
LazyServiceProvider.GetRequiredService<OmsRbacUserDisplayNameResolver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询客户列表。
|
/// 查询客户列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -57,7 +60,16 @@ public class CustomerService : ApplicationService
|
|||||||
new Dictionary<string, bool> { [nameof(Customer.UpdateTime)] = false, [nameof(Customer.Id)] = false });
|
new Dictionary<string, bool> { [nameof(Customer.UpdateTime)] = false, [nameof(Customer.Id)] = false });
|
||||||
|
|
||||||
var totalCount = await CustomerRepository.CountAsync(predicate);
|
var totalCount = await CustomerRepository.CountAsync(predicate);
|
||||||
var items = entities.Select(entity => ObjectMapper.Map<Customer, CustomerPaginatedOutput>(entity)).ToList();
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
entities.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
|
||||||
|
var items = entities.Select(entity =>
|
||||||
|
{
|
||||||
|
var output = ObjectMapper.Map<Customer, CustomerPaginatedOutput>(entity);
|
||||||
|
output.CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap);
|
||||||
|
output.UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap);
|
||||||
|
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
|
||||||
|
return output;
|
||||||
|
}).ToList();
|
||||||
|
|
||||||
return new OmsPageResult<CustomerPaginatedOutput>
|
return new OmsPageResult<CustomerPaginatedOutput>
|
||||||
{
|
{
|
||||||
@ -82,8 +94,10 @@ public class CustomerService : ApplicationService
|
|||||||
{
|
{
|
||||||
var entity = await GetCustomerOrThrowAsync(id);
|
var entity = await GetCustomerOrThrowAsync(id);
|
||||||
var output = ObjectMapper.Map<Customer, CustomerOutput>(entity);
|
var output = ObjectMapper.Map<Customer, CustomerOutput>(entity);
|
||||||
output.CreateBy = entity.CreateUserId <= 0 ? null : entity.CreateUserId.ToString();
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
output.UpdateBy = entity.UpdateUserId <= 0 ? null : entity.UpdateUserId.ToString();
|
[entity.CreateUserId, entity.UpdateUserId]);
|
||||||
|
output.CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap);
|
||||||
|
output.UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap);
|
||||||
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
|
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,9 @@ public partial class OrderService
|
|||||||
: await CountryRepository.GetListAsync(x => countryCodes.Contains(x.CountryCode));
|
: await CountryRepository.GetListAsync(x => countryCodes.Contains(x.CountryCode));
|
||||||
var countryMap = countries.ToDictionary(x => x.CountryCode, StringComparer.OrdinalIgnoreCase);
|
var countryMap = countries.ToDictionary(x => x.CountryCode, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
|
orders.SelectMany(x => new[] { x.CreateUserId, x.UpdateUserId }));
|
||||||
|
|
||||||
return orders.Select(order =>
|
return orders.Select(order =>
|
||||||
{
|
{
|
||||||
senderMap.TryGetValue(order.Id, out var sender);
|
senderMap.TryGetValue(order.Id, out var sender);
|
||||||
@ -127,9 +130,9 @@ public partial class OrderService
|
|||||||
IsIntercept = order.IsIntercept > 0,
|
IsIntercept = order.IsIntercept > 0,
|
||||||
IsRemote = order.IsRemote > 0,
|
IsRemote = order.IsRemote > 0,
|
||||||
CreateTime = order.CreateTime,
|
CreateTime = order.CreateTime,
|
||||||
CreateBy = order.CreateUserId <= 0 ? null : order.CreateUserId.ToString(),
|
CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(order.CreateUserId, auditUserNameMap),
|
||||||
UpdateTime = OmsDocHelper.NullIfDefault(order.UpdateTime),
|
UpdateTime = OmsDocHelper.NullIfDefault(order.UpdateTime),
|
||||||
UpdateBy = order.UpdateUserId <= 0 ? null : order.UpdateUserId.ToString(),
|
UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(order.UpdateUserId, auditUserNameMap),
|
||||||
Sender = MapSender(sender),
|
Sender = MapSender(sender),
|
||||||
Receiver = MapReceiver(recipient),
|
Receiver = MapReceiver(recipient),
|
||||||
Items = (items ?? []).Select(MapDeclaration).ToList(),
|
Items = (items ?? []).Select(MapDeclaration).ToList(),
|
||||||
|
|||||||
@ -28,6 +28,8 @@ public partial class OrderService : ApplicationService
|
|||||||
private IWarehouseAddressRepository WarehouseAddressRepository => LazyServiceProvider.GetRequiredService<IWarehouseAddressRepository>();
|
private IWarehouseAddressRepository WarehouseAddressRepository => LazyServiceProvider.GetRequiredService<IWarehouseAddressRepository>();
|
||||||
private ISalesProductRepository SalesProductRepository => LazyServiceProvider.GetRequiredService<ISalesProductRepository>();
|
private ISalesProductRepository SalesProductRepository => LazyServiceProvider.GetRequiredService<ISalesProductRepository>();
|
||||||
private IWebHostEnvironment WebHostEnvironment => LazyServiceProvider.GetRequiredService<IWebHostEnvironment>();
|
private IWebHostEnvironment WebHostEnvironment => LazyServiceProvider.GetRequiredService<IWebHostEnvironment>();
|
||||||
|
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
|
||||||
|
LazyServiceProvider.GetRequiredService<OmsRbacUserDisplayNameResolver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询订单列表。
|
/// 查询订单列表。
|
||||||
|
|||||||
@ -18,6 +18,9 @@ public class WarehouseService : ApplicationService
|
|||||||
{
|
{
|
||||||
private IWarehouseAddressRepository WarehouseAddressRepository => LazyServiceProvider.GetRequiredService<IWarehouseAddressRepository>();
|
private IWarehouseAddressRepository WarehouseAddressRepository => LazyServiceProvider.GetRequiredService<IWarehouseAddressRepository>();
|
||||||
|
|
||||||
|
private OmsRbacUserDisplayNameResolver UserDisplayNameResolver =>
|
||||||
|
LazyServiceProvider.GetRequiredService<OmsRbacUserDisplayNameResolver>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询仓库列表。
|
/// 查询仓库列表。
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -74,8 +77,10 @@ public class WarehouseService : ApplicationService
|
|||||||
{
|
{
|
||||||
var entity = await GetWarehouseOrThrowAsync(id);
|
var entity = await GetWarehouseOrThrowAsync(id);
|
||||||
var output = ObjectMapper.Map<WarehouseAddress, WarehouseOutput>(entity);
|
var output = ObjectMapper.Map<WarehouseAddress, WarehouseOutput>(entity);
|
||||||
output.CreateBy = entity.CreateUserId <= 0 ? null : entity.CreateUserId.ToString();
|
var auditUserNameMap = await UserDisplayNameResolver.ResolveManyAsync(
|
||||||
output.UpdateBy = entity.UpdateUserId <= 0 ? null : entity.UpdateUserId.ToString();
|
[entity.CreateUserId, entity.UpdateUserId]);
|
||||||
|
output.CreateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.CreateUserId, auditUserNameMap);
|
||||||
|
output.UpdateBy = OmsRbacUserDisplayNameResolver.FormatUserId(entity.UpdateUserId, auditUserNameMap);
|
||||||
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
|
output.UpdateTime = OmsDocHelper.NullIfDefault(entity.UpdateTime);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/Oms.Application/Shared/OmsRbacUserDisplayNameResolver.cs
Normal file
80
src/Oms.Application/Shared/OmsRbacUserDisplayNameResolver.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Fake.DependencyInjection;
|
||||||
|
using Fake.Rbac.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Oms.Application.Shared;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将 OMS 审计字段中的 RBAC mapId(user.userid)解析为展示名称。
|
||||||
|
/// </summary>
|
||||||
|
public class OmsRbacUserDisplayNameResolver : IScopedDependency
|
||||||
|
{
|
||||||
|
private readonly FakeRbacDbContext _rbacDbContext;
|
||||||
|
|
||||||
|
public OmsRbacUserDisplayNameResolver(FakeRbacDbContext rbacDbContext)
|
||||||
|
{
|
||||||
|
_rbacDbContext = rbacDbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string?> ResolveAsync(int userId, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (userId <= 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var map = await ResolveManyAsync([userId], cancellationToken);
|
||||||
|
return FormatUserId(userId, map);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<IReadOnlyDictionary<int, string>> ResolveManyAsync(
|
||||||
|
IEnumerable<int> userIds,
|
||||||
|
CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var ids = userIds.Where(x => x > 0).Distinct().ToList();
|
||||||
|
if (ids.Count == 0)
|
||||||
|
{
|
||||||
|
return new Dictionary<int, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
var sql =
|
||||||
|
$"SELECT `userid` AS `{nameof(RbacUserNameRow.UserId)}`, `Name` AS `{nameof(RbacUserNameRow.DisplayName)}` FROM `user` WHERE `IsDeleted` = 0 AND `userid` IN ({string.Join(",", ids)})";
|
||||||
|
var rows = await _rbacDbContext.Database
|
||||||
|
.SqlQueryRaw<RbacUserNameRow>(sql)
|
||||||
|
.ToListAsync(cancellationToken);
|
||||||
|
|
||||||
|
return rows.ToDictionary(
|
||||||
|
x => x.UserId,
|
||||||
|
x => NormalizeDisplayName(x.DisplayName, x.UserId));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? FormatUserId(int userId, IReadOnlyDictionary<int, string>? nameMap)
|
||||||
|
{
|
||||||
|
if (userId <= 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nameMap != null &&
|
||||||
|
nameMap.TryGetValue(userId, out var name) &&
|
||||||
|
!string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return userId.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string NormalizeDisplayName(string? name, int userId)
|
||||||
|
{
|
||||||
|
var trimmed = name?.Trim();
|
||||||
|
return string.IsNullOrWhiteSpace(trimmed) ? userId.ToString() : trimmed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class RbacUserNameRow
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
|
||||||
|
public string? DisplayName { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user