using Admin.NET.Plugin.AiDOP.Manufacturing.Dto;
namespace Admin.NET.Plugin.AiDOP.Manufacturing;
///
/// S6 生产指令单 只读消费服务(Phase 1A)。
///
/// 数据源:数据中台标准层 mdp_std_work_order_schedule(S2/Production 从工单主表贴源
/// → mdp_stg_schedule → 标准化而来;specification 由 S2 转换层从物料主数据 enrich)。
///
/// 只读铁律:本服务只 SELECT mdp_std_*,绝不直连源库业务表(工单主表 / 物料主表 / MES 工单表),绝不回退源库、绝不写库。
///
/// 租户隔离(P0):租户只来自认证后 JWT(AidopTenantScope.ResolveOrThrow),忽略前端传入的任何 tenantId;
/// COUNT / PAGE / DETAIL 三处 SQL 都显式带 tenant_id = @TenantId(mdp_std 实体非 ITenantIdFilter,不依赖框架自动过滤)。
/// 工厂隔离:当前 S6 体系只可靠解析租户、无稳定工厂作用域 → FACTORY_SCOPE = PARTIAL(tenant-only,不硬编码 factory_id)。
///
[ApiDescriptionSettings(Order = 305, Description = "生产指令单")]
[Route("api/S6ProductionInstruction")]
[NonUnify]
public class S6ProductionInstructionService : IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
private readonly UserManager _userManager;
public S6ProductionInstructionService(ISqlSugarClient db, UserManager userManager)
{
_db = db;
_userManager = userManager;
}
/// 严格可信租户解析,见 。
private long ResolveTenantOrThrow() => Infrastructure.AidopTenantScope.ResolveOrThrow(_userManager);
private const string SelectColumns = """
m.id AS Id,
m.work_order AS WorkOrderNo,
m.lot_serial AS LotSerial,
m.item_code AS ItemCode,
m.item_name AS ItemName,
m.specification AS Specification,
m.drawing_no AS DrawingNo,
m.project AS Project,
m.qty_ordered AS OrderQty,
m.qty_completed AS CompletedQty,
m.order_date AS OrderDate,
m.due_date AS DueDate,
m.status AS Status,
m.work_order_type AS WorkOrderType
""";
///
/// 生产指令单列表(只读真分页)。
///
[DisplayName("生产指令单列表")]
[HttpGet("page")]
public async Task