admin/src/Oms.Application/Shared/OmsSessionHelper.cs
zzh c6e765e6e2
All checks were successful
Build and Deploy / deploy (push) Successful in 1m2s
fix: 公告列表用 mapId 解析当前用户,管理端可查全部
同步监控 overview 支持日周月经营指标与积压队列。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 09:48:42 +08:00

162 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Security.Claims;
using Fake.Application;
using Fake.Users;
using Oms.Domain.CustomersAggregate.Entities;
using Oms.Domain.CustomersAggregate.Repositories;
namespace Oms.Application.Shared;
/// <summary>
/// 从 JWT Claims 解析当前会话类型(管理员 / 客户)。
/// </summary>
public static class OmsSessionHelper
{
/// <summary>
/// JWT 中标识登录类型的 Claim 名称。
/// </summary>
public const string LoginTypeClaim = "loginType";
/// <summary>
/// JWT 中 RBAC mapId Claim 名称(与 FakeClaimTypes.UserId 对齐)。
/// </summary>
public const string MapIdClaim = "mapId";
private const string CustomerLoginType = "1";
private const string CustomerRoleName = "Customer";
/// <summary>
/// 当前会话是否为客户门户登录。
/// </summary>
public static bool IsCustomerLogin(ICurrentUser currentUser)
{
if (string.Equals(
currentUser.FindClaimOrNull(LoginTypeClaim)?.Value,
CustomerLoginType,
StringComparison.Ordinal))
{
return true;
}
// 兼容 loginType 丢失但 role=Customer 仍在的令牌
var role = currentUser.FindClaimOrNull(ClaimTypes.Role)?.Value
?? currentUser.FindClaimOrNull("role")?.Value;
return string.Equals(role, CustomerRoleName, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// 解析当前会话的 RBAC mapId(user.userid)。
/// JWT nameidentifier 多为 Guid,GetId&lt;int&gt; 常为 0,需回退读 mapId claim。
/// </summary>
public static int ResolveMapUserId(ICurrentUser currentUser)
{
var userId = currentUser.GetId<int>();
if (userId > 0)
{
return userId;
}
var mapIdRaw = currentUser.FindClaimOrNull(MapIdClaim)?.Value;
if (int.TryParse(mapIdRaw, out var mapId) && mapId > 0)
{
return mapId;
}
return 0;
}
/// <summary>
/// 客户登录时返回 mapId(对应 t_customer.UserId / 订单 CreateUserId);管理员返回 null。
/// </summary>
public static int? TryGetCustomerMapId(ICurrentUser currentUser)
{
if (!IsCustomerLogin(currentUser))
{
return null;
}
var mapId = ResolveMapUserId(currentUser);
return mapId > 0 ? mapId : null;
}
/// <summary>
/// 客户登录时返回 mapId(对应订单 CreateUserId);管理员返回 null(不过滤)。
/// </summary>
public static int? TryGetCustomerCreateUserId(ICurrentUser currentUser) =>
TryGetCustomerMapId(currentUser);
/// <summary>
/// 解析当前会话对应的 t_customer 记录(客户按 UserId=mapId;管理员可按 CustomerId 代提交)。
/// </summary>
public static async Task<Customer> ResolveSessionCustomerAsync(
ICustomerRepository customerRepository,
ICurrentUser currentUser,
int? requestedCustomerId = null)
{
var mapId = TryGetCustomerMapId(currentUser);
if (mapId.HasValue)
{
var sessionCustomer = await customerRepository.FirstOrDefaultAsync(x => x.UserId == mapId.Value);
if (sessionCustomer == null)
{
throw new BusinessException("未找到客户信息");
}
if (requestedCustomerId is > 0 && requestedCustomerId.Value != sessionCustomer.Id)
{
throw new BusinessException("客户ID非法");
}
return sessionCustomer;
}
var customerId = requestedCustomerId ?? currentUser.GetId<int>();
if (customerId <= 0)
{
throw new BusinessException("客户ID不能为空");
}
var customer = await customerRepository.FirstOrDefaultAsync(x => x.Id == customerId);
if (customer == null)
{
throw new BusinessException("客户不存在");
}
return customer;
}
/// <summary>
/// 客户登录时强制返回 t_customer.Id;管理员返回入参 customerId。
/// </summary>
public static async Task<int?> ResolveListCustomerIdAsync(
ICustomerRepository customerRepository,
ICurrentUser currentUser,
int? requestedCustomerId)
{
var mapId = TryGetCustomerMapId(currentUser);
if (!mapId.HasValue)
{
return requestedCustomerId;
}
var customer = await customerRepository.FirstOrDefaultAsync(x => x.UserId == mapId.Value);
if (customer == null)
{
throw new BusinessException("未找到客户信息");
}
return customer.Id;
}
/// <summary>
/// 小红书模块客户上下文:客户登录返回 t_customer.Id;管理员无客户上下文时返回 0(系统级)。
/// </summary>
public static async Task<int> ResolveXhsCustomerIdAsync(
ICustomerRepository customerRepository,
ICurrentUser currentUser,
int? requestedCustomerId = null)
{
var customerId = await ResolveListCustomerIdAsync(customerRepository, currentUser, requestedCustomerId);
return customerId ?? 0;
}
}