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