namespace Admin.NET.Plugin.AiDOP.Production;
///
/// 工单工序排产服务 🏭
/// 路由前缀:/api/Production/scheduling/...
///
[ApiDescriptionSettings(Order = 265, Description = "工单工序排产")]
[Route("api/Production")]
[AllowAnonymous]
[NonUnify]
public class WorkOrderSchedulingService : IDynamicApiController, ITransient
{
private readonly ISqlSugarClient _db;
private readonly UserManager _userManager;
public WorkOrderSchedulingService(ISqlSugarClient db, UserManager userManager)
{
_db = db;
_userManager = userManager;
}
///
/// 主表 WorkOrdMaster 按工单号 +「公司域或租户 id」匹配:domain 可为原 Domain 列,或与 tenant_id 相同的字符串(列表已做 COALESCE 回传)。
///
private const string SqlWorkOrdMasterMatchDomainOrTenant = """
WorkOrd = @WorkOrd AND (
TRIM(IFNULL(`Domain`, '')) = TRIM(@Domain)
OR (
TRIM(IFNULL(`Domain`, '')) = ''
AND TRIM(@Domain) <> ''
AND CAST(IFNULL(tenant_id, 0) AS CHAR) = TRIM(@Domain)
)
)
""";
/// 带表别名的 WorkOrdMaster 匹配(参数 alias 为表别名,如 a、w)。
private static string SqlWorkOrdMasterMatchDomainOrTenantAliased(string alias) => $"""
{alias}.WorkOrd = @WorkOrd AND (
TRIM(IFNULL({alias}.`Domain`, '')) = TRIM(@Domain)
OR (
TRIM(IFNULL({alias}.`Domain`, '')) = ''
AND TRIM(@Domain) <> ''
AND CAST(IFNULL({alias}.tenant_id, 0) AS CHAR) = TRIM(@Domain)
)
)
""";
/// 子表(工序/明细)按工单号 + 域或主表租户匹配。
private static string SqlWorkOrdChildMatchDomainOrTenant(string childAlias, string masterAlias) => $"""
{childAlias}.WorkOrd = @WorkOrd AND (
TRIM(IFNULL({childAlias}.`Domain`, '')) = TRIM(@Domain)
OR EXISTS (
SELECT 1 FROM WorkOrdMaster {masterAlias}
WHERE {masterAlias}.WorkOrd = {childAlias}.WorkOrd
AND (
TRIM(IFNULL({masterAlias}.`Domain`, '')) = TRIM(@Domain)
OR (
TRIM(IFNULL({masterAlias}.`Domain`, '')) = ''
AND TRIM(@Domain) <> ''
AND CAST(IFNULL({masterAlias}.tenant_id, 0) AS CHAR) = TRIM(@Domain)
)
)
)
)
""";
/// 按主键 +「公司域或租户 id」匹配(状态更新等)。
private const string SqlWorkOrdMasterMatchRecIdAndDomainOrTenant = """
RecID = @Id AND (
TRIM(IFNULL(`Domain`, '')) = TRIM(@Domain)
OR (
TRIM(IFNULL(`Domain`, '')) = ''
AND TRIM(@Domain) <> ''
AND CAST(IFNULL(tenant_id, 0) AS CHAR) = TRIM(@Domain)
)
)
""";
// ══════════════════════════════════════════════════════════════
// 列表 GET /api/Production/scheduling/list
// ══════════════════════════════════════════════════════════════
/// 工单工序排产分页列表(MySQL 口径,与 WorkOrdMaster 等表一致)
[DisplayName("工单工序排产列表")]
[HttpGet("scheduling/list")]
public async Task