Files

166 lines
6.8 KiB
C#

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
{
/// <summary>
/// JSON 模板引擎实现 | JSON template engine implementation
/// 负责加载、反序列化和验证 JSON 格式的报告模板
/// Responsible for loading, deserializing and validating JSON report templates
/// </summary>
public class JsonTemplateEngine : ITemplateEngine
{
private readonly ILoggerService _logger;
/// <summary>
/// 默认样式定义(当模板引用未定义的样式名称时使用)
/// Default style definition (used when template references undefined style name)
/// </summary>
public static readonly StyleDefinition DefaultStyle = new()
{
Font = null,
Size = 12f,
Bold = false,
Italic = false,
Color = "#000000",
Align = "left",
BackgroundColor = null
};
/// <summary>
/// 构造函数 | Constructor
/// </summary>
/// <param name="logger">日志服务 | Logger service</param>
public JsonTemplateEngine(ILoggerService logger)
{
_logger = logger?.ForModule<JsonTemplateEngine>() ?? throw new ArgumentNullException(nameof(logger));
}
/// <summary>
/// 加载并反序列化 JSON 模板文件 | Load and deserialize JSON template file
/// </summary>
/// <param name="templatePath">模板文件路径 | Template file path</param>
/// <returns>解析后的模板对象,文件不存在时返回 null | Parsed template object, null if file not found</returns>
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<ReportTemplate>(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);
}
}
/// <summary>
/// 验证模板结构完整性 | Validate template structure integrity
/// 检查 document、pages、styles 必需字段是否存在
/// Checks if required fields (document, pages, styles) are present
/// </summary>
/// <param name="template">待验证的模板 | Template to validate</param>
/// <returns>验证结果 | Validation result</returns>
public TemplateValidationResult Validate(ReportTemplate template)
{
if (template == null)
{
return TemplateValidationResult.Invalid("模板对象为 null | Template object is null");
}
var missingFields = new List<string>();
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();
}
/// <summary>
/// 解析样式名称,未定义时回退为默认样式 | Resolve style name, fallback to default if undefined
/// </summary>
/// <param name="template">报告模板 | Report template</param>
/// <param name="styleName">样式名称 | Style name</param>
/// <returns>解析后的样式定义 | Resolved style definition</returns>
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;
}
}
}