using Admin.NET.Plugin.AiDOP.MaterialWarehouse.Dto;
namespace Admin.NET.Plugin.AiDOP.MaterialWarehouse;
///
/// S5 委外发料单 只读 list/detail 服务。
///
/// 数据源:DOP 数据中台标准层 mdp_std_outsource_issue(头)/ mdp_std_outsource_issue_detail(明细)。
/// 由 OutsourceIssueMdpSyncService 从 aidopdev.NbrMaster/NbrDetail Type='CA' 同步标准化而来。
///
/// 本服务仅 SELECT:无新增/编辑/删除/写入;明细只暴露已确认 9 列(发料数量/已发数/批次号 3 候选列后置)。
/// 当前上游未产 CA 单据,标准层为空,list 返回空数组、detail 返回 null(前端空态)。
///
[ApiDescriptionSettings(Order = 304, Description = "委外发料单")]
[Route("api/OutsourceIssue")]
[NonUnify]
public class OutsourceIssueService : IDynamicApiController, ITransient
{
/// 主/系统租户哨兵:超管未选择目标租户时其 JWT TenantId 即此值,拒绝作为业务租户。
private const long MainTenantId = 1300000000001L;
private readonly ISqlSugarClient _db;
private readonly UserManager _userManager;
public OutsourceIssueService(ISqlSugarClient db, UserManager userManager)
{
_db = db;
_userManager = userManager;
}
/// 严格可信租户解析:只来自认证后 JWT;无 Token(<=0) 或超管未选主租户 → 拒绝;不读前端 tenantId、无默认回退。
private long ResolveTenantOrThrow()
{
var tid = _userManager.TenantId;
if (tid <= 0)
throw Oops.Oh("无法确定当前租户,请重新登录或选择目标租户");
if (_userManager.SuperAdmin && tid == MainTenantId)
throw Oops.Oh("超级管理员操作前必须选择目标租户");
return tid;
}
///
/// 委外发料单列表(只读分页查询)。
///
[DisplayName("委外发料单列表")]
[HttpGet("list")]
public async Task