using FreeSql.DataAnnotations;
using F9WebAiTest.Domain.Events.SYS.Reports;
namespace F9WebAiTest.Domain.Entities.SYS.Reports;
///
/// 报表定义(Grid++Report 模板)。每张报表对应一个 .grf 模板与一段数据查询 SQL。
/// 权限模型:创建/更新报表时自动同步一条 Permission(ResourceType=报表),
/// 角色在「角色管理 - 报表权限」中分配给用户后即可在报表中心查看。
///
[Table(Name = "sys_reports")]
public class Report : AggregateRoot
{
[Column(Name = "code")]
public string Code { get; private set; } = ""; // 唯一标识,作为权限码的 resourceIdentity
[Column(Name = "name")]
public string Name { get; private set; } = ""; // 显示名称
[Column(Name = "category")]
public string Category { get; private set; } = "通用"; // 分类
[Column(Name = "description")]
public string Description { get; private set; } = ""; // 描述
/// 数据集 SQL(必须以 SELECT 开头)。FreeSql ExecuteDataTable 执行。
[Column(Name = "data_sql")]
public string DataSql { get; private set; } = "";
/// 数据集查询参数定义 JSON:[{"name":"deptId","label":"部门","type":"int","default":0}]
[Column(Name = "data_params")]
public string DataParams { get; private set; } = "[]";
///
/// 查询配置 JSON(F9 ReportConfig 约定):
/// { "DsName":"查询名(后端 IReportDataProvider 解析)", "ViewerType":0,
/// "Parms":[{ "Name":"q_yearmonth","Label":"账期","Prompt":"","IsRequired":false,
/// "ControlType":"AntdUI.DatePickerYearMonth","Ds_Static":null,"Ds_Service":null,"DefaultValue":"" }] }
/// DsName 优先于 DataSql。
///
[Column(Name = "config")]
public string Config { get; private set; } = "";
///
/// 报表模板文件 Id(对齐 F9 Report.ReportFileId)。
/// 模板实例存储在 ReportFile(sys_report_files.DesignContent),与报表定义分离。
///
[Column(Name = "report_file_id")]
public long ReportFileId { get; private set; }
// ---------- 以下三个字段已废弃(历史遗留列,仅供启动时把旧模板迁移到 ReportFile 读取) ----------
// 新代码一律通过 ReportFile.DesignContent 读写模板。
/// [已废弃] 旧版模板二进制,迁移到 ReportFile 后不再写入
[Column(Name = "template_data", MapType = typeof(byte[]))]
public byte[]? TemplateData { get; private set; }
[Column(Name = "template_name")]
public string TemplateName { get; private set; } = "";
[Column(Name = "template_size")]
public int TemplateSize { get; private set; }
[Column(Name = "sort_order")]
public int SortOrder { get; private set; }
[Column(Name = "is_active")]
public bool IsActive { get; private set; } = true;
public Report() { }
public Report(long id, string code, string name, string category, string description, string dataSql, string dataParams, int sortOrder, string config = "")
{
Id = id;
Code = code ?? "";
Name = name ?? "";
Category = string.IsNullOrWhiteSpace(category) ? "通用" : category.Trim();
Description = description ?? "";
DataSql = dataSql ?? "";
DataParams = string.IsNullOrWhiteSpace(dataParams) ? "[]" : dataParams;
Config = config ?? "";
SortOrder = sortOrder;
IsActive = true;
CreatedAt = DateTime.Now;
AddDomainEvent(new Report_ChangedDomainEvent(Id));
}
public void UpdateBasic(string code, string name, string category, string description, string dataSql, string dataParams, int sortOrder, string? config = null)
{
Code = code ?? Code;
Name = name ?? Name;
Category = string.IsNullOrWhiteSpace(category) ? Category : category.Trim();
Description = description ?? Description;
DataSql = dataSql ?? DataSql;
DataParams = string.IsNullOrWhiteSpace(dataParams) ? DataParams : dataParams;
Config = config ?? Config;
SortOrder = sortOrder;
UpdatedAt = DateTime.Now;
AddDomainEvent(new Report_ChangedDomainEvent(Id));
}
/// [已废弃] 旧版把模板二进制直接写在报表上;现模板存于 ReportFile.DesignContent
public void UploadTemplate(byte[] data, string fileName)
{
TemplateData = data ?? Array.Empty();
TemplateName = fileName ?? "";
TemplateSize = TemplateData.Length;
UpdatedAt = DateTime.Now;
AddDomainEvent(new Report_ChangedDomainEvent(Id));
}
/// 绑定模板文件实例(对齐 F9:Report.ReportFileId → ReportFile)
public void BindReportFile(long reportFileId)
{
ReportFileId = reportFileId;
UpdatedAt = DateTime.Now;
AddDomainEvent(new Report_ChangedDomainEvent(Id));
}
/// 迁移完成后清空废弃的旧模板字段
public void ClearLegacyTemplate()
{
TemplateData = null;
TemplateName = "";
TemplateSize = 0;
}
public void Activate() { IsActive = true; UpdatedAt = DateTime.Now; AddDomainEvent(new Report_ChangedDomainEvent(Id)); }
public void Deactivate() { IsActive = false; UpdatedAt = DateTime.Now; AddDomainEvent(new Report_ChangedDomainEvent(Id)); }
}