using Admin.NET.Plugin.AiDOP.Dto.S8;
using Admin.NET.Plugin.AiDOP.Entity.S8;
using Admin.NET.Plugin.AiDOP.Infrastructure;
namespace Admin.NET.Plugin.AiDOP.Service.S8;
///
/// S8-RULE-GOVERNANCE-BATCH4:主动提报模板的**只读**查询。
///
/// 为什么会有这个服务:Batch 3 退役配置向导时,审计结论是
/// 「草稿 Controller 整体只服务 Wizard」—— 这条判断不完整。
/// ado_s8_config_draft 上还骑着第二个消费方:主动提报页把
/// mechanism = MANUAL_REPORT 的草稿当作**提报模板**使用
/// (TASK-022-MANUAL-REPORT-TEMPLATE-1)。删掉整个 Controller 之后该功能已经死了,
/// 而且是**静默**死的 —— 前端 list 走 catch 把模板列表置空,用户只会觉得"模板怎么没了"。
///
/// 本服务把那一半补回来,且只补只读的一半:
///
/// - 只有 GET;没有 Create / Update / Delete;
/// - 没有 GenerateRule —— 生成规则那条路已经永久关闭;
/// - 只返回 mechanism = MANUAL_REPORT 的行,其余(历史规则向导草稿)一律不可见。
///
///
/// 命名刻意不叫 draft / wizard:正是那个名字让 Batch 3 把两个不同的功能
/// 当成了同一个。路由与类型都改叫 report-template,让下一个读代码的人一眼看出它服务谁。
///
/// 实体与表仍按既有口径 KEEP_TEMPORARILY,后续 schema 清理时再决定是否拆表。
///
public class S8ReportTemplateService : ITransient
{
/// 主动提报模板的机制标识。只有该值的草稿行才被视为模板。
public const string ManualReportMechanism = "MANUAL_REPORT";
private readonly SqlSugarRepository _rep;
public S8ReportTemplateService(SqlSugarRepository rep) => _rep = rep;
/// 按可信作用域列出本租户 / 工厂的主动提报模板。
public async Task> ListAsync(S8TrustedScope scope)
{
var rows = await ScopedQuery(scope)
.OrderBy(x => x.Id)
.ToListAsync();
return rows.Select(x => new S8ReportTemplateRowDto
{
Id = x.Id,
TemplateCode = x.DraftCode,
TemplateName = x.DraftName,
Mechanism = x.Mechanism,
StageCode = x.StageCode,
OrderFlowCode = x.OrderFlowCode,
ExceptionTypeCode = x.ExceptionTypeCode
}).ToList();
}
///
/// 取模板详情(含 wizardJson 原文,由前端解析后填表)。
/// 越权 / 非 MANUAL_REPORT 的 id 一律按「不存在」处理,不泄露它是否存在。
///
public async Task GetAsync(long id, S8TrustedScope scope)
{
var row = await ScopedQuery(scope).Where(x => x.Id == id).FirstAsync()
?? throw new S8NotFoundException();
return new S8ReportTemplateDetailDto
{
Id = row.Id,
TemplateCode = row.DraftCode,
TemplateName = row.DraftName,
Mechanism = row.Mechanism,
StageCode = row.StageCode,
OrderFlowCode = row.OrderFlowCode,
ExceptionTypeCode = row.ExceptionTypeCode,
TemplateJson = row.WizardJson
};
}
///
/// 作用域 + 机制双重过滤。
/// 机制过滤不是可选项:库里还躺着历史的规则向导草稿,
/// 放它们出来等于给已退役的建规则流程留了一个只读展示面。
///
private ISugarQueryable ScopedQuery(S8TrustedScope scope) =>
_rep.AsQueryable()
.Where(x => x.TenantId == scope.TenantId)
.Where(x => x.Mechanism == ManualReportMechanism);
}