2025-10-02 17:35:35 +08:00
|
|
|
|
using System.Data;
|
|
|
|
|
|
using System.Globalization;
|
2025-09-15 20:54:32 +08:00
|
|
|
|
using DMS.Application.DTOs;
|
|
|
|
|
|
using DMS.Application.Interfaces;
|
|
|
|
|
|
using DMS.Application.Models;
|
2025-10-03 00:05:17 +08:00
|
|
|
|
using DMS.Core.Enums;
|
2025-09-15 20:54:32 +08:00
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
|
|
|
|
|
|
|
|
namespace DMS.Application.Services.Processors;
|
|
|
|
|
|
|
|
|
|
|
|
public class ValueConvertProcessor : IVariableProcessor
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly ILogger<ValueConvertProcessor> _logger;
|
|
|
|
|
|
|
|
|
|
|
|
public ValueConvertProcessor(ILogger<ValueConvertProcessor> logger)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
}
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
|
|
|
|
|
public Task ProcessAsync(VariableContext context)
|
2025-09-15 20:54:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
var oldValue = context.Data.DataValue;
|
2025-10-03 00:05:17 +08:00
|
|
|
|
// 如果值没有变化则中断处理链
|
|
|
|
|
|
if (context.Data.DataValue == context.NewValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
context.IsHandled = true;
|
|
|
|
|
|
}
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
|
|
|
|
|
// 步骤 1: 将原始值转换为 DataValue 和 NumericValue
|
2025-10-03 00:05:17 +08:00
|
|
|
|
context.Data.DataValue = context.NewValue;
|
|
|
|
|
|
if (context.Data.DataType == DataType.Bool)
|
|
|
|
|
|
{
|
|
|
|
|
|
context.Data.NumericValue=context.NewValue=="True"?1:0;
|
|
|
|
|
|
context.Data.DisplayValue = context.NewValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (double.TryParse(context.Data.DataValue, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsedFromStr))
|
|
|
|
|
|
{
|
|
|
|
|
|
context.Data.NumericValue = parsedFromStr;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
// 步骤 2: 根据公式计算 DisplayValue
|
|
|
|
|
|
CalculateDisplayValue(context.Data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
2025-10-03 00:05:17 +08:00
|
|
|
|
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
2025-09-15 20:54:32 +08:00
|
|
|
|
context.Data.UpdatedAt = DateTime.Now;
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
2025-10-03 00:05:17 +08:00
|
|
|
|
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
|
|
|
|
|
return Task.CompletedTask;
|
2025-09-15 20:54:32 +08:00
|
|
|
|
}
|
2025-10-02 17:35:35 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据转换公式计算用于UI显示的DisplayValue
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="variable">需要处理的变量DTO</param>
|
|
|
|
|
|
private void CalculateDisplayValue(VariableDto variable)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 默认情况下,显示值等于原始数据值
|
|
|
|
|
|
variable.DisplayValue = variable.DataValue;
|
|
|
|
|
|
|
|
|
|
|
|
// 如果没有转换公式,则直接返回
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(variable.ConversionFormula))
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
// 将公式中的 'x' 替换为实际的数值
|
|
|
|
|
|
// 使用 InvariantCulture 确保小数点是 '.'
|
|
|
|
|
|
string expression = variable.ConversionFormula.ToLowerInvariant()
|
|
|
|
|
|
.Replace("x", variable.NumericValue.ToString(CultureInfo.InvariantCulture));
|
|
|
|
|
|
|
|
|
|
|
|
// 使用 DataTable.Compute 来安全地计算表达式
|
|
|
|
|
|
var result = new DataTable().Compute(expression, null);
|
|
|
|
|
|
|
2025-10-02 23:14:40 +08:00
|
|
|
|
// 将计算结果格式化后赋给 DisplayValue
|
|
|
|
|
|
if (result is double || result is decimal || result is float)
|
|
|
|
|
|
{
|
|
|
|
|
|
variable.DisplayValue = string.Format("{0:F2}", result); // 默认格式化为两位小数,可根据需要调整
|
|
|
|
|
|
variable.NumericValue = Convert.ToDouble(result); // 更新NumericValue为计算后的值
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
variable.DisplayValue = result.ToString();
|
|
|
|
|
|
// 尝试将字符串结果解析回double,以更新NumericValue
|
|
|
|
|
|
if (double.TryParse(result.ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out var parsedResult))
|
|
|
|
|
|
{
|
|
|
|
|
|
variable.NumericValue = parsedResult;
|
|
|
|
|
|
}
|
|
|
|
|
|
} }
|
2025-10-02 17:35:35 +08:00
|
|
|
|
catch (Exception ex)
|
|
|
|
|
|
{
|
|
|
|
|
|
_logger.LogError(ex, $"为变量 {variable.Name} (ID: {variable.Id}) 计算DisplayValue时出错。公式: '{variable.ConversionFormula}'");
|
|
|
|
|
|
// 如果计算出错,DisplayValue 将保持为原始的 DataValue,保证程序健壮性
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-15 20:54:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 将从 S7 读取的对象值转换为字符串表示和数值表示
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="variable">关联的变量 DTO</param>
|
|
|
|
|
|
/// <param name="value">从 S7 读取的原始对象值</param>
|
2025-10-03 00:05:17 +08:00
|
|
|
|
private void ConvertS7ValueToStringAndNumeric(VariableDto variable, string value)
|
2025-09-15 20:54:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
if (value == null)
|
2025-10-02 17:35:35 +08:00
|
|
|
|
return;
|
2025-09-15 20:54:32 +08:00
|
|
|
|
|
|
|
|
|
|
string directConversion = null;
|
|
|
|
|
|
double numericValue = 0.0;
|
2025-10-03 00:05:17 +08:00
|
|
|
|
if (variable.DataType == DataType.Bool)
|
2025-09-15 20:54:32 +08:00
|
|
|
|
{
|
2025-10-03 00:05:17 +08:00
|
|
|
|
numericValue=value.ToString()=="True"?1.0:0.0;
|
|
|
|
|
|
directConversion = value.ToString();
|
|
|
|
|
|
return;
|
2025-09-15 20:54:32 +08:00
|
|
|
|
}
|
2025-10-03 00:05:17 +08:00
|
|
|
|
|
2025-09-15 20:54:32 +08:00
|
|
|
|
|
|
|
|
|
|
variable.DataValue = directConversion ?? value.ToString() ?? string.Empty;
|
|
|
|
|
|
variable.NumericValue = numericValue;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|