using SqlSugar;
namespace FoodLabeling.Application.Helpers;
///
/// 探测标签模板 Company/Region scope 列与关联表是否已迁移(fl_label_template_scope.sql)。
/// 未迁移时 ORM 实体不含 AppliedPartnerType/AppliedRegionType,读写走 raw SQL 或关联表推断。
///
public static class LabelTemplateScopeSchemaHelper
{
private static LabelTemplateScopeSchemaStatus? _cached;
public sealed class LabelTemplateScopeSchemaStatus
{
public bool HasAppliedPartnerTypeColumn { get; init; }
public bool HasAppliedRegionTypeColumn { get; init; }
public bool HasPartnerScopeTable { get; init; }
public bool HasRegionScopeTable { get; init; }
/// partner/region 关联表均已创建(用于多选明细)。
public bool HasPartnerRegionScopeTables => HasPartnerScopeTable && HasRegionScopeTable;
/// 列 + 关联表均已迁移。
public bool IsFullSchema =>
HasAppliedPartnerTypeColumn
&& HasAppliedRegionTypeColumn
&& HasPartnerRegionScopeTables;
}
public static async Task GetStatusAsync(ISqlSugarClient db)
{
if (_cached is not null)
{
return _cached;
}
try
{
var partnerColCount = await db.Ado.GetIntAsync(
"""
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'fl_label_template'
AND COLUMN_NAME = 'AppliedPartnerType'
""");
var regionColCount = await db.Ado.GetIntAsync(
"""
SELECT COUNT(*)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'fl_label_template'
AND COLUMN_NAME = 'AppliedRegionType'
""");
var partnerTableCount = await db.Ado.GetIntAsync(
"""
SELECT COUNT(*)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'fl_label_template_partner'
""");
var regionTableCount = await db.Ado.GetIntAsync(
"""
SELECT COUNT(*)
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'fl_label_template_region'
""");
_cached = new LabelTemplateScopeSchemaStatus
{
HasAppliedPartnerTypeColumn = partnerColCount > 0,
HasAppliedRegionTypeColumn = regionColCount > 0,
HasPartnerScopeTable = partnerTableCount > 0,
HasRegionScopeTable = regionTableCount > 0
};
}
catch
{
_cached = new LabelTemplateScopeSchemaStatus();
}
return _cached;
}
/// 单元测试或切换库后调用。
public static void ResetCacheForTests() => _cached = null;
///
/// 是否已创建 fl_label_template_partner 与 fl_label_template_region。
///
public static async Task HasPartnerRegionScopeTablesAsync(ISqlSugarClient db)
{
var status = await GetStatusAsync(db);
return status.HasPartnerRegionScopeTables;
}
///
/// 已迁移 scope 列时,写入 AppliedPartnerType / AppliedRegionType(未迁移则 no-op)。
///
public static async Task SetAppliedScopeTypesAsync(
ISqlSugarClient db,
string templateId,
string appliedPartnerType,
string appliedRegionType)
{
if (string.IsNullOrWhiteSpace(templateId))
{
return;
}
var status = await GetStatusAsync(db);
if (!status.HasAppliedPartnerTypeColumn && !status.HasAppliedRegionTypeColumn)
{
return;
}
if (status.HasAppliedPartnerTypeColumn && status.HasAppliedRegionTypeColumn)
{
await db.Ado.ExecuteCommandAsync(
"""
UPDATE fl_label_template
SET AppliedPartnerType = @partnerType,
AppliedRegionType = @regionType
WHERE Id = @id
""",
new
{
partnerType = appliedPartnerType.Trim(),
regionType = appliedRegionType.Trim(),
id = templateId.Trim()
});
return;
}
if (status.HasAppliedPartnerTypeColumn)
{
await db.Ado.ExecuteCommandAsync(
"UPDATE fl_label_template SET AppliedPartnerType = @type WHERE Id = @id",
new { type = appliedPartnerType.Trim(), id = templateId.Trim() });
}
if (status.HasAppliedRegionTypeColumn)
{
await db.Ado.ExecuteCommandAsync(
"UPDATE fl_label_template SET AppliedRegionType = @type WHERE Id = @id",
new { type = appliedRegionType.Trim(), id = templateId.Trim() });
}
}
}