//
// ReSharper disable All
// Disable StyleCop analysis for this file
//
// Copyright (c) Manus. All rights reserved.
//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace YbTest.Models
{
///
/// JSON配置转换服务类
///
public class TransformerService
{
private readonly TransformationConfig _config;
private readonly IValueConverter _valueConverter; // 用于字典转换等
///
/// 构造函数
///
/// 转换配置
/// 值转换器实例 (可选)
public TransformerService(TransformationConfig configuration, IValueConverter valueConverter = null)
{
_config = configuration ?? throw new ArgumentNullException(nameof(configuration));
_valueConverter = valueConverter ?? new DefaultValueConverter(); // 提供一个默认实现
}
///
/// 从JSON字符串加载配置
///
/// 包含配置的JSON字符串
/// TransformationConfig 实例
public static TransformationConfig LoadConfigFromJson(string jsonConfig)
{
if (string.IsNullOrWhiteSpace(jsonConfig))
{
throw new ArgumentException("JSON configuration string cannot be null or empty.", nameof(jsonConfig));
}
try
{
return JsonSerializer.Deserialize(jsonConfig, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true // 允许属性名不区分大小写
});
}
catch (JsonException ex)
{
// 在实际应用中,这里应该记录更详细的错误日志
throw new InvalidOperationException("Failed to deserialize JSON configuration.", ex);
}
}
///
/// 将源数据对象根据指定方法转换为目标JSON字符串 (系统对象 -> 接口JSON)
///
/// 方法名称 (来自 method_config)
/// 源数据对象 (通常是一个C#对象或字典)
/// 转换后的JSON字符串
public string Transform(string methodName, object sourceObject)
{
// 1. 查找方法配置
var method = _config.MethodConfigs.FirstOrDefault(m => m.METHOD_NAME == methodName);
if (method == null)
{
throw new ArgumentException($"Method '{methodName}' not found in configuration.", nameof(methodName));
}
// 2. 筛选出适用于当前方法和出参的组装规则 (parametr_type = 2 代表出参)
var assemblyRules = _config.ObjectAssemblies
.Where(a => a.METHOD_REF == method.METHOD_ID && a.PARAMETR_TYPE == 2 && a.ASSEMBLY_TYPE == "interface") // 假设是系统到接口的转换
.OrderBy(a => a.OBJECT_PATH) // 排序以确保父节点先创建
.ToList();
if (!assemblyRules.Any())
{
// 如果没有找到针对出参的interface类型组装规则,可能需要抛出错误或返回空JSON
// 根据实际需求,这里也可以查找 'sys' 类型的规则,取决于转换方向的定义
Console.WriteLine($"Warning: No 'interface' assembly rules found for method '{methodName}' and parameter type 2 (output).");
return "{}"; // 或者抛出异常
}
var rootNode = new JsonObject(); // 创建JSON根节点
// 3. 遍历组装规则,构建JSON
foreach (var rule in assemblyRules)
{
// 3.1 查找对应的映射规则 (通过MappingTable关联到ObjectMapping的ObjectTableName或MappingId)
// 假设 MappingTable 直接对应 ObjectMapping 中的 ObjectTableName
var mapping = _config.ObjectMappings.FirstOrDefault(om => om.OBJECT_TABLE_NAME == rule.MAPPING_TABLE && om.INTERFACE_FIELD != null);
// 如果MappingTable也可能是MappingId, 则需要调整查找逻辑
// var mapping = _config.ObjectMappings.FirstOrDefault(om =>
// (om.ObjectTableName == rule.MappingTable || om.MappingId == rule.MappingTable) &&
// om.InterfaceField != null);
if (mapping == null)
{
Console.WriteLine($"Warning: No object mapping found for MappingTable '{rule.MAPPING_TABLE}' in assembly rule '{rule.ID}'. Skipping path '{rule.OBJECT_PATH}'.");
continue;
}
// 3.2 从源对象获取值
// 这里简化处理,假设sourceObject是字典或可以通过反射获取属性
// 实际应用中需要更健壮的取值逻辑
object sourceValue = GetValueFromSourceObject(sourceObject, mapping.SYSTEM_FIELD);
if (sourceValue == null && rule.OBJECT_PATH.Contains("patientId")) // 示例:特定字段的空值处理
{
// Console.WriteLine($"Debug: Source value for {mapping.SystemField} is null.");
}
// 3.3 值转换 (字典翻译、类型转换等)
object convertedValue = _valueConverter.Convert(
sourceValue,
mapping.SYSTEM_FIELD_TYPE?.ToString(), // Convert decimal? to string
mapping.OBJECT_FIELD_TYPE?.ToString(), // Convert decimal? to string
mapping.SYSTEM_DICT_NAME,
mapping.OBJECT_DICT_NAME,
rule.PARAMETR_TYPE
);
// 3.4 根据ObjectPath设置值到JSON节点
SetValueByJsonPath(rootNode, rule.OBJECT_PATH, convertedValue, rule.OBJECT_TYPE);
}
return rootNode.ToJsonString(new JsonSerializerOptions { WriteIndented = true });
}
///
/// 从源对象中获取指定属性的值 (简化实现)
///
private object GetValueFromSourceObject(object source, string propertyName)
{
if (source == null || string.IsNullOrEmpty(propertyName)) return null;
if (source is IDictionary dictSource)
{
return dictSource.TryGetValue(propertyName, out var val) ? val : null;
}
if (source is JsonElement jsonElementSource && jsonElementSource.ValueKind == JsonValueKind.Object)
{
return jsonElementSource.TryGetProperty(propertyName, out var prop) ? GetValueFromJsonElement(prop) : null;
}
// 尝试通过反射获取属性值
var propInfo = source.GetType().GetProperty(propertyName);
if (propInfo != null)
{
return propInfo.GetValue(source);
}
// 如果是JsonNode,尝试获取
if (source is JsonNode jnSource)
{
var parts = propertyName.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
JsonNode currentNode = jnSource;
foreach (var part in parts)
{
if (currentNode is JsonObject jo && jo.ContainsKey(part))
{
currentNode = jo[part];
}
else
{
return null; // 路径不存在
}
}
if (currentNode is JsonValue jv) return jv.GetValue