using System; using System.Collections.Generic; using System.IO; using Newtonsoft.Json; using XP.Common.Logging.Interfaces; using XP.ReportEngine.Interfaces; using XP.ReportEngine.Models; namespace XP.ReportEngine.Services { /// /// JSON 模板引擎实现 | JSON template engine implementation /// 负责加载、反序列化和验证 JSON 格式的报告模板 /// Responsible for loading, deserializing and validating JSON report templates /// public class JsonTemplateEngine : ITemplateEngine { private readonly ILoggerService _logger; /// /// 默认样式定义(当模板引用未定义的样式名称时使用) /// Default style definition (used when template references undefined style name) /// public static readonly StyleDefinition DefaultStyle = new() { Font = null, Size = 12f, Bold = false, Italic = false, Color = "#000000", Align = "left", BackgroundColor = null }; /// /// 构造函数 | Constructor /// /// 日志服务 | Logger service public JsonTemplateEngine(ILoggerService logger) { _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } /// /// 加载并反序列化 JSON 模板文件 | Load and deserialize JSON template file /// /// 模板文件路径 | Template file path /// 解析后的模板对象,文件不存在时返回 null | Parsed template object, null if file not found public ReportTemplate LoadTemplate(string templatePath) { if (string.IsNullOrWhiteSpace(templatePath)) { _logger.Warn("模板文件路径为空 | Template file path is null or empty"); return null; } if (!File.Exists(templatePath)) { _logger.Warn("模板文件未找到: {Path} | Template file not found: {Path}", templatePath); return null; } _logger.Info("开始加载模板文件: {Path} | Loading template file: {Path}", templatePath); try { var json = File.ReadAllText(templatePath); var template = JsonConvert.DeserializeObject(json); _logger.Info("模板文件加载成功 | Template file loaded successfully"); return template; } catch (JsonReaderException ex) { // JSON 语法错误,包含错误位置信息 | JSON syntax error with position info var message = $"模板 JSON 语法错误,行 {ex.LineNumber},位置 {ex.LinePosition}: {ex.Message} | " + $"Template JSON syntax error at line {ex.LineNumber}, position {ex.LinePosition}: {ex.Message}"; _logger.Error(ex, message); throw new InvalidOperationException(message, ex); } catch (JsonSerializationException ex) { // JSON 反序列化错误 | JSON deserialization error var message = $"模板 JSON 反序列化失败: {ex.Message} | Template JSON deserialization failed: {ex.Message}"; _logger.Error(ex, message); throw new InvalidOperationException(message, ex); } } /// /// 验证模板结构完整性 | Validate template structure integrity /// 检查 document、pages、styles 必需字段是否存在 /// Checks if required fields (document, pages, styles) are present /// /// 待验证的模板 | Template to validate /// 验证结果 | Validation result public TemplateValidationResult Validate(ReportTemplate template) { if (template == null) { return TemplateValidationResult.Invalid("模板对象为 null | Template object is null"); } var missingFields = new List(); if (template.Document == null) { missingFields.Add("document"); } if (template.Pages == null || template.Pages.Count == 0) { missingFields.Add("pages"); } if (template.Styles == null) { missingFields.Add("styles"); } if (missingFields.Count > 0) { var fieldList = string.Join(", ", missingFields); var message = $"模板缺少必需字段: {fieldList} | Template missing required fields: {fieldList}"; _logger.Warn(message); return TemplateValidationResult.Invalid(message); } _logger.Info("模板验证通过 | Template validation passed"); return TemplateValidationResult.Valid(); } /// /// 解析样式名称,未定义时回退为默认样式 | Resolve style name, fallback to default if undefined /// /// 报告模板 | Report template /// 样式名称 | Style name /// 解析后的样式定义 | Resolved style definition public StyleDefinition ResolveStyle(ReportTemplate template, string styleName) { // 样式名称为空时直接返回默认样式 | Return default style if style name is empty if (string.IsNullOrWhiteSpace(styleName)) { return DefaultStyle; } // 模板或样式字典为空时返回默认样式 | Return default style if template or styles dictionary is null if (template?.Styles == null) { _logger.Warn("模板样式字典为空,使用默认样式: {StyleName} | Template styles dictionary is null, using default style: {StyleName}", styleName); return DefaultStyle; } // 查找样式,找到则返回,否则回退为默认样式并记录警告 // Look up style, return if found, otherwise fallback to default and log warning if (template.Styles.TryGetValue(styleName, out var style)) { return style; } _logger.Warn("未定义的样式名称 '{StyleName}',使用默认样式 | Undefined style name '{StyleName}', using default style", styleName); return DefaultStyle; } } }