710 lines
22 KiB
C#
710 lines
22 KiB
C#
using BaseFunction;
|
|
using NSAnalysis.DAL;
|
|
using NSAnalysis.Model;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace NSAnalysis
|
|
{
|
|
public class FileSorter
|
|
{
|
|
public CjlrDAL _dal = new CjlrDAL();
|
|
|
|
//定义读取的位置
|
|
public int readRowIndex = 2; // 默认读取第3行(从0开始计数)
|
|
|
|
public int readColIndex = 1; // 默认读取第2列(从0开始计数)
|
|
|
|
public event Action<string> OnLog; // 日志事件
|
|
|
|
public event Action<string, string> OnFileParsed; // 解析完成后通知文件名
|
|
|
|
// 关键流程节点日志事件
|
|
public event Action<string> OnProcessStep; // 处理步骤日志事件
|
|
|
|
// 封装 OnProcessStep 事件
|
|
private void emitProcessStep(string message)
|
|
{
|
|
OnProcessStep?.Invoke(message);
|
|
//Console.WriteLine(message); // 控制台输出
|
|
}
|
|
|
|
public FileSorter()
|
|
{
|
|
//SQLHelper.connStr = DatabaseDfn.SqlConnectStr();
|
|
}
|
|
|
|
// 主逻辑处理
|
|
public void ProcessFiles()
|
|
{
|
|
var tasks = GetTaskRecords();
|
|
// 增加空检查
|
|
if (tasks == null || tasks.Rows.Count == 0)
|
|
{
|
|
Trace("没有找到任何任务记录,处理终止。");
|
|
return;
|
|
}
|
|
foreach (DataRow task in tasks.Rows)
|
|
{
|
|
string modelName = task["modelsName"].ToString();
|
|
string modelCode = task["modelsCode"].ToString();
|
|
string position = task["position"].ToString();
|
|
string sourceDir = task["sourceFile"].ToString();
|
|
string targetDir = task["targetFile"].ToString();
|
|
|
|
// 打印信息
|
|
Trace($"[ProcessFiles] 正在执行分发任务 - 源路径: {sourceDir}, 目标路径: {targetDir}, 匹配字符: {modelCode} 位置:{position}");
|
|
if (Directory.Exists(sourceDir))
|
|
{
|
|
ProcessDirectory(sourceDir, targetDir, modelCode, modelName, position);
|
|
}
|
|
else
|
|
{
|
|
Trace($"[ProcessFiles] 源文件地址不存在或错误: {sourceDir}");
|
|
}
|
|
}
|
|
}
|
|
|
|
// 获取任务记录
|
|
private DataTable GetTaskRecords()
|
|
{
|
|
DataTable dt = _dal.SelectTaskByCondition("", "", "start");
|
|
|
|
//打印 dt
|
|
//PrintDataTable(dt);
|
|
if (dt == null || dt.Rows.Count == 0)
|
|
{
|
|
Trace("未发现移动任务.");
|
|
return null;
|
|
}
|
|
return dt;
|
|
}
|
|
|
|
// 处理目录中的文件
|
|
private void ProcessDirectory(string sourceDir, string targetDir, string modelCode, string modelName, string position)
|
|
{
|
|
// 匹配信息
|
|
string matchStr = $"{modelCode}_{position}";
|
|
Trace($"匹配文件特征符: {matchStr}");
|
|
|
|
// 判断目标目录是否存在,如果不存在记录到日志
|
|
|
|
// 确保目标目录存在
|
|
if (!Directory.Exists(targetDir))
|
|
{
|
|
Directory.CreateDirectory(targetDir);
|
|
Trace($"创建目标文件夹: {targetDir}");
|
|
}
|
|
|
|
// 遍历源目录中的所有CSV文件
|
|
foreach (string file in Directory.GetFiles(sourceDir, "*.csv"))
|
|
{
|
|
// 打印正在处理的文件
|
|
Trace($"正在处理文件 : {file}");
|
|
|
|
// 解析入库
|
|
AnalysisNxsCSV(file);
|
|
|
|
// 如果未启用分发功能,直接返回
|
|
if (!ConfigDfn.iEnableSort)
|
|
{
|
|
return;
|
|
}
|
|
|
|
#region 分发逻辑
|
|
|
|
if (MatchCsvValue(file, matchStr, readRowIndex, readColIndex))
|
|
{
|
|
// 记录日志,匹配到
|
|
Trace($"匹配成功,准备移动文件: {file} -> {targetDir}");
|
|
|
|
string destFile = Path.Combine(targetDir, Path.GetFileName(file));
|
|
if (File.Exists(destFile))
|
|
{
|
|
// 生成备份文件名,格式如:xxx.csv.bak_20240613_153012
|
|
string backupFile = destFile + ".bak_" + DateTime.Now.ToString("yyyyMMdd_HHmmss");
|
|
File.Move(destFile, backupFile);
|
|
Trace($"目标文件已存在,已重命名为备份文件: {backupFile}");
|
|
}
|
|
File.Move(file, destFile);
|
|
Trace($"移动完成,: {file} -> {destFile}");
|
|
emitProcessStep($"---> 5、文件移动完成: -> {destFile}");
|
|
|
|
//插入分发详情
|
|
CjlrTaskReleaseDetailModel detailModel = new CjlrTaskReleaseDetailModel
|
|
{
|
|
ModelsName = modelName, // 这里可以根据需要填写车型名称
|
|
ModelsCode = modelCode,
|
|
Position = position, // 这里可以根据需要填写位置
|
|
SourceFile = file,
|
|
TargetFile = destFile,
|
|
TaskFileName = Path.GetFileName(file),
|
|
TaskStatus = 1, // 假设1表示已处理
|
|
TaskDetail = "文件移动成功",
|
|
CreateDate = DateTime.Now
|
|
};
|
|
_dal.InsertTaskDetail(detailModel);
|
|
}
|
|
else
|
|
{
|
|
Trace($"未匹配到文件: {file}");
|
|
emitProcessStep($"---> 5、未匹配到文件: {file}");
|
|
|
|
//记录到数据库
|
|
CjlrTaskReleaseDetailModel detailModel = new CjlrTaskReleaseDetailModel
|
|
{
|
|
ModelsName = modelName, // 这里可以根据需要填写车型名称
|
|
ModelsCode = modelCode,
|
|
Position = position, // 这里可以根据需要填写位置
|
|
SourceFile = file,
|
|
TargetFile = "",
|
|
TaskFileName = Path.GetFileName(file),
|
|
TaskStatus = 2, // 假设2表示未处理
|
|
TaskDetail = "文件未匹配",
|
|
CreateDate = DateTime.Now
|
|
};
|
|
try
|
|
{
|
|
_dal.InsertTaskDetail(detailModel);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Trace($"记录错误到数据库失败: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
#endregion 分发逻辑
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查CSV文件中指定行列的字符串是否匹配目标值
|
|
/// </summary>
|
|
/// <param name="filePath">CSV文件路径</param>
|
|
/// <param name="targetValue">要匹配的目标字符串</param>
|
|
/// <param name="rowIndex">行索引(从0开始)</param>
|
|
/// <param name="colIndex">列索引(从0开始)</param>
|
|
/// <returns>匹配成功返回true,否则false</returns>
|
|
public static bool MatchCsvValue(string filePath, string targetValue, int rowIndex, int colIndex)
|
|
{
|
|
// 记录日志 输入
|
|
MyBase.TraceWriteLine($"[MatchCsvValue] 检查文件: {filePath}, 行索引: {rowIndex}, 列索引: {colIndex}, 目标值: {targetValue}");
|
|
try
|
|
{
|
|
string[] lines = File.ReadAllLines(filePath);
|
|
|
|
// 检查行索引是否有效
|
|
if (rowIndex < 0 || rowIndex >= lines.Length)
|
|
return false;
|
|
|
|
string[] columns = lines[rowIndex].Split(',');
|
|
|
|
// 检查列索引是否有效
|
|
if (colIndex < 0 || colIndex >= columns.Length)
|
|
return false;
|
|
|
|
return columns[colIndex].Trim().Contains(targetValue); //改为包含
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MyBase.TraceWriteLine($"处理CSV文件时出错: {ex.Message}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 生成单侧统计信息的方法
|
|
private void GenerateSingleSideStatistics(string GroupName, string Position)
|
|
{
|
|
#region 统计信息显示
|
|
|
|
DataTable sampleData = _dal.SelectMeasureResultByCarID(ConfigDfn.strEquipNo, GroupName);
|
|
if (sampleData == null || sampleData.Rows.Count == 0)
|
|
{
|
|
MyBase.TraceWriteLine("没有测量数据,无法生成统计信息。");
|
|
// 触发日志事件
|
|
emitProcessStep(Position + " 没有测量数据,无法生成统计信息。");
|
|
return;
|
|
}
|
|
|
|
// 提取分析结果
|
|
AnalysisResult analysis = AnalysisResult.AnalyzeMeasureData(sampleData);
|
|
//AnalysisResult.DisplayAnalysisResult(analysis);
|
|
|
|
//表格行数
|
|
int dtRowCount = analysis.TotalCount;
|
|
//超差个数
|
|
double OutCount = analysis.OutCount;
|
|
//Ok个数
|
|
double OKCount = analysis.OKCount;
|
|
//异常个数
|
|
double RejectedCount = analysis.RejectedCount;
|
|
//合格率
|
|
double FPYPercent = analysis.FPYPercent;
|
|
|
|
TMeasureResultModel tmrm = new TMeasureResultModel();
|
|
|
|
FPYPercent = OKCount / (OKCount + OutCount);
|
|
if (FPYPercent >= ConfigDfn.dFPY)
|
|
{
|
|
tmrm.Result = 1;
|
|
}
|
|
else if (FPYPercent >= ConfigDfn.dFPY2 && FPYPercent < ConfigDfn.dFPY)
|
|
{
|
|
tmrm.Result = 1;
|
|
}
|
|
else
|
|
{
|
|
tmrm.Result = 2;
|
|
}
|
|
|
|
tmrm.CarID = ConfigDfn.strEquipNo;
|
|
tmrm.CarType = ConfigDfn.strCarModel;
|
|
tmrm.SumMeasureItems = dtRowCount;
|
|
tmrm.GoodMeasureItems = (int)OKCount;
|
|
tmrm.NoGoodMeasureItems = (int)OutCount;
|
|
tmrm.RejectMeasureItems = (int)RejectedCount;
|
|
tmrm.FPY = FPYPercent.ToString("F4");
|
|
tmrm.Remark = Position; //区分左右侧
|
|
tmrm.MeasureDate = ConfigDfn.strMeasureTime;
|
|
_dal.InsertTMeasureResult(tmrm);
|
|
|
|
MyBase.TraceWriteLine("将总结果插入数据库完毕。");
|
|
emitProcessStep($"---> 3、统计信息已生成: 位置: {Position}, 总测量项: {dtRowCount}, 合格项: {OKCount}, 不合格项: {OutCount}, 异常项: {RejectedCount}, FPY: {FPYPercent:F4}");
|
|
|
|
#endregion 统计信息显示
|
|
}
|
|
|
|
// 导入CSV文件到数据库
|
|
public void ImportCsv2Sql(string filePath)
|
|
{
|
|
var records = new List<CJLR_MeaDataModel>();
|
|
var lineNo = 0; // 行号计数器
|
|
var groupName = string.Empty; // 组名变量
|
|
var position = string.Empty; // 位置变量
|
|
|
|
emitProcessStep($"正在处理: {filePath}");
|
|
|
|
// 判断文件是否已经处理过
|
|
if (_dal.IsFileProcessed(filePath))
|
|
{
|
|
MyBase.TraceWriteLine($"文件已处理过,跳过: {filePath}");
|
|
emitProcessStep($"---> 2、文件已处理过,跳过: {filePath}");
|
|
return;
|
|
}
|
|
|
|
// 解析数据之前,备份原始数据,如果已存在备份文件,则覆盖, 备份到 程序根目录\Backup 文件夹
|
|
try
|
|
{
|
|
string backupDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Backup");
|
|
if (!Directory.Exists(backupDir))
|
|
{
|
|
Directory.CreateDirectory(backupDir);
|
|
}
|
|
string backupFilePath = Path.Combine(backupDir, Path.GetFileName(filePath));
|
|
File.Copy(filePath, backupFilePath, true); // 如果存在则覆盖
|
|
MyBase.TraceWriteLine("已备份文件到: " + backupFilePath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MyBase.TraceWriteLine("备份文件时发生错误:" + ex.Message);
|
|
// 继续处理,不返回
|
|
}
|
|
|
|
try
|
|
{
|
|
using (var reader = new StreamReader(filePath))
|
|
{
|
|
// Skip header
|
|
reader.ReadLine();
|
|
|
|
lineNo = 1; // 初始化行号计数器
|
|
while (!reader.EndOfStream)
|
|
{
|
|
lineNo++; // 增加行号计数器
|
|
var line = reader.ReadLine();
|
|
var values = line.Split(','); // 假设 CSV 使用制表符分隔
|
|
|
|
// 跳过前两行(如果有标题行或其他非数据行
|
|
if (string.IsNullOrWhiteSpace(line) || line.StartsWith("#") || line.StartsWith("//") || line.StartsWith("MeasPoint.Name"))
|
|
{
|
|
continue; // 跳过空行或注释行
|
|
}
|
|
|
|
// 跳过前两行(如果有标题行或其他非数据行),理论应该有19列
|
|
if (values.Length < 22)
|
|
{
|
|
MyBase.TraceWriteLine("CSV行数据不完整,跳过该行:" + line);
|
|
continue; // 跳过不完整的行
|
|
}
|
|
|
|
// 判断 values[2] 是否为 ,如果是则跳过该行
|
|
if (string.IsNullOrEmpty(values[2]))
|
|
{
|
|
MyBase.TraceWriteLine($"第 {lineNo} 行数据为0,跳过该行:" + line);
|
|
continue; // 跳过该行
|
|
}
|
|
|
|
// 创建 MeasurementRecord 对象并填充数据
|
|
var record = new CJLR_MeaDataModel
|
|
{
|
|
PointName = values[0],
|
|
GroupName = values[1],
|
|
ProductNum = values[2],
|
|
Model = values[3],
|
|
Station = values[4],
|
|
Method = values[5],
|
|
Standard = values[6],
|
|
DimensionName = values[7],
|
|
DimensionValue = values[8],
|
|
DimensionUnit = values[9],
|
|
IsManual = bool.Parse(values[10]),
|
|
Classification = values[11],
|
|
ToleranceName0 = values[12],
|
|
ToleranceLower0 = values[13],
|
|
ToleranceUpper0 = values[14],
|
|
ToleranceName1 = values[15],
|
|
ToleranceLower1 = values[16],
|
|
ToleranceUpper1 = values[17],
|
|
NominalValue = values[18],
|
|
MeasureDate = DateTime.ParseExact(values[19], "yyyyMMdd", CultureInfo.InvariantCulture),
|
|
MeasureTime = TimeSpan.ParseExact(values[20], "hhmmss", CultureInfo.InvariantCulture),
|
|
SequenceNum = int.Parse(values[21])
|
|
};
|
|
|
|
records.Add(record);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MyBase.TraceWriteLine("导入CSV文件时发生错误:" + ex.Message);
|
|
|
|
// 将错误信息通过事件传递出去
|
|
emitProcessStep($"---> 2、导入CSV文件时发生错误: {ex.Message}");
|
|
|
|
// 1、解析出错的,移动到 源路径文件夹\Error 文件夹
|
|
string errorDir = Path.Combine(Path.GetDirectoryName(filePath), "Error");
|
|
if (!Directory.Exists(errorDir))
|
|
{
|
|
Directory.CreateDirectory(errorDir);
|
|
}
|
|
string errorFilePath = Path.Combine(errorDir, Path.GetFileName(filePath));
|
|
File.Move(filePath, errorFilePath);
|
|
// 记录到日志
|
|
MyBase.TraceWriteLine("已将文件移动到错误文件夹: " + errorFilePath);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// 取第一条记录的时间作为测量时间
|
|
if (records.Count > 0)
|
|
{
|
|
var firstRecord = records[0];
|
|
ConfigDfn.strMeasureTime = firstRecord.MeasureDate.ToString("yyyy-MM-dd") + " " + firstRecord.MeasureTime.ToString(@"hh\:mm\:ss");
|
|
// 记录时间
|
|
MyBase.TraceWriteLine("测量时间:" + ConfigDfn.strMeasureTime);
|
|
|
|
// 获取车号
|
|
MyBase.TraceWriteLine("--------------------------------------------------------");
|
|
ConfigDfn.strEquipNo = firstRecord.ProductNum;
|
|
MyBase.TraceWriteLine("车号:" + ConfigDfn.strEquipNo);
|
|
|
|
ConfigDfn.strCarModel = firstRecord.Model; //获取车型
|
|
MyBase.TraceWriteLine("车型:" + ConfigDfn.strCarModel);
|
|
|
|
// 从 firstRecord.GroupName 中提取位置 ,使用下划线分隔 例如:X540_R,提取 R 作为位置
|
|
groupName = firstRecord.GroupName;
|
|
MyBase.TraceWriteLine("组名:" + firstRecord.GroupName);
|
|
// 如果 GroupName 为空,则使用默认位置
|
|
if (string.IsNullOrEmpty(firstRecord.GroupName))
|
|
{
|
|
MyBase.TraceWriteLine("组名为空,使用默认位置。");
|
|
ConfigDfn.strEquipPosition = "Default"; // 默认位置
|
|
}
|
|
else
|
|
{
|
|
// 使用下划线分隔 GroupName,提取最后一部分作为位置
|
|
var parts2 = firstRecord.GroupName.Split('_');
|
|
if (parts2.Length > 1 && !string.IsNullOrEmpty(parts2[1]))
|
|
{
|
|
// 提取下划线后第一个字符
|
|
ConfigDfn.strEquipPosition = parts2[1].Substring(0, 1);
|
|
}
|
|
else
|
|
{
|
|
ConfigDfn.strEquipPosition = firstRecord.GroupName; // 如果没有下划线,直接使用原值
|
|
}
|
|
}
|
|
|
|
// 打印提取后位置
|
|
MyBase.TraceWriteLine("位置:" + ConfigDfn.strEquipPosition);
|
|
|
|
MyBase.TraceWriteLine("测量时间:" + ConfigDfn.strMeasureTime);
|
|
|
|
emitProcessStep($"---> 1、解析到, 车号: {ConfigDfn.strEquipNo} 车型: {ConfigDfn.strCarModel} 位置: {ConfigDfn.strEquipPosition} 测量时间: {ConfigDfn.strMeasureTime}");
|
|
}
|
|
else
|
|
{
|
|
MyBase.TraceWriteLine("没有找到有效的测量记录,无法设置测量时间。CSV文件导入到数据库失败!");
|
|
//将错误信息
|
|
emitProcessStep($"---> 2、没有找到有效的测量记录,无法设置测量时间。CSV文件导入到数据库失败!");
|
|
|
|
// 2、解析未出错(有可能整个文件被跳过),但没有有效数据的,移动到 源路径文件夹\Error 文件夹
|
|
string errorDir = Path.Combine(Path.GetDirectoryName(filePath), "Error");
|
|
if (!Directory.Exists(errorDir))
|
|
{
|
|
Directory.CreateDirectory(errorDir);
|
|
}
|
|
string errorFilePath = Path.Combine(errorDir, Path.GetFileName(filePath));
|
|
File.Move(filePath, errorFilePath);
|
|
// 记录到日志
|
|
MyBase.TraceWriteLine("已将文件移动到错误文件夹: " + errorFilePath);
|
|
|
|
return;
|
|
}
|
|
|
|
// 逐条插入数据到数据库
|
|
foreach (var record in records)
|
|
{
|
|
_dal.InsertOrUpdateCJLRMeaData(record);
|
|
}
|
|
|
|
// 记录处理文件到数据库
|
|
_dal.InsertProcessedFile(filePath);
|
|
MyBase.TraceWriteLine("CSV文件导入到数据库成功!");
|
|
emitProcessStep($"---> 2、CSV文件导入到数据库成功");
|
|
|
|
#region 处理单侧统计信息
|
|
|
|
GenerateSingleSideStatistics(groupName, ConfigDfn.strEquipPosition);
|
|
|
|
#endregion 处理单侧统计信息
|
|
|
|
MyBase.TraceWriteLine("--------------------------------------------------------");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MyBase.TraceWriteLine("导入CSV文件时发生错误:" + ex.Message);
|
|
emitProcessStep($"---> 2、导入CSV文件时发生错误: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
//解析EH3 CSV文件函数
|
|
public void AnalysisNxsCSV(string strCSVName)
|
|
{
|
|
// 判断文件是否存在
|
|
if (!File.Exists(strCSVName))
|
|
{
|
|
MyBase.TraceWriteLine("文件不存在:" + strCSVName);
|
|
return;
|
|
}
|
|
|
|
try
|
|
{
|
|
// 解析 CSV 文件并导入到数据库
|
|
ImportCsv2Sql(strCSVName);
|
|
|
|
// 解析完成后触发事件
|
|
if (!string.IsNullOrEmpty(ConfigDfn.strEquipNo))
|
|
{
|
|
// 构造 事件参数
|
|
Trace($"触发事件,车号: {ConfigDfn.strEquipNo} 位置: {ConfigDfn.strEquipPosition}");
|
|
OnFileParsed?.Invoke(ConfigDfn.strEquipNo, ConfigDfn.strEquipPosition);
|
|
}
|
|
|
|
// 每次解析完一个文件后,检查是否有双侧测量结果
|
|
bool isMeasureComplete = _dal.HasBothSidesMeasureResult(ConfigDfn.strEquipNo);
|
|
|
|
if (isMeasureComplete)
|
|
{
|
|
MyBase.TraceWriteLine("双侧测量结果已完成,开始生成客户报告。");
|
|
emitProcessStep($"---> 4、双侧测量结果已完成,开始生成客户报告,车号: {ConfigDfn.strEquipNo}");
|
|
// 生成客户报告
|
|
GenCustomerReport(ConfigDfn.strEquipNo);
|
|
}
|
|
else
|
|
{
|
|
MyBase.TraceWriteLine("双侧测量结果未完成,跳过客户报告生成。");
|
|
emitProcessStep($"---> 4、双侧测量结果未完成,跳过客户报告生成,车号: {ConfigDfn.strEquipNo}");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MyBase.TraceWriteLine("解析 CSV 文件时发生错误:" + ex.Message);
|
|
}
|
|
}
|
|
|
|
// 生成客户报告函数
|
|
private void GenCustomerReport(string strCarID)
|
|
{
|
|
// 从数据库获取测量数据
|
|
DataTable dtCSVContent = _dal.SelectPointDimensionByCarID(strCarID);
|
|
|
|
if (dtCSVContent == null || dtCSVContent.Rows.Count == 0)
|
|
{
|
|
MyBase.TraceWriteLine("没有找到测量数据,无法生成客户报告。");
|
|
return;
|
|
}
|
|
|
|
// 生成报告
|
|
string fileName = strCarID + "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".csv";
|
|
|
|
// 确保报告路径存在
|
|
if (!Directory.Exists(ConfigDfn.strReportPath))
|
|
{
|
|
Directory.CreateDirectory(ConfigDfn.strReportPath);
|
|
MyBase.TraceWriteLine($"创建报告目录: {ConfigDfn.strReportPath}");
|
|
}
|
|
|
|
// 构造备份路径 ,备份到 程序根目录\ReportBackup 文件夹
|
|
string backupDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ReportBackup");
|
|
if (!Directory.Exists(backupDir))
|
|
{
|
|
Directory.CreateDirectory(backupDir);
|
|
}
|
|
|
|
// 备份文件完整路径
|
|
string savePath = Path.Combine(backupDir, fileName);
|
|
|
|
// 目标路径
|
|
string target = Path.Combine(ConfigDfn.strReportPath, fileName);
|
|
|
|
GenerateCsvReport(strCarID, dtCSVContent, ConfigDfn.strCSVReportTemplatePath, savePath);
|
|
|
|
MyBase.TraceWriteLine($"客户报告已生成: {savePath}");
|
|
|
|
// 将备份路径,拷贝到目标路径
|
|
emitProcessStep($"---> 5、客户报告已生成: {savePath}");
|
|
try
|
|
{
|
|
File.Copy(savePath, target, true); // 如果存在则覆盖
|
|
//记录成功
|
|
MyBase.TraceWriteLine("已拷贝客户报告到目标路径: " + target);
|
|
emitProcessStep($"---> 6、已拷贝客户报告到目标路径: {target}");
|
|
}
|
|
catch
|
|
{
|
|
MyBase.TraceWriteLine("拷贝客户报告到目标路径失败: " + target);
|
|
|
|
emitProcessStep($"---> 6、拷贝客户报告到目标路径失败: {target}");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// 生成CSV报告函数
|
|
private void GenerateCsvReport(string strCarID, DataTable measureData, string templatePath, string savePath)
|
|
{
|
|
// 读取模板内容
|
|
var templateLines = File.ReadAllLines(templatePath);
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
// 替换模板中的变量
|
|
foreach (var line in templateLines)
|
|
{
|
|
string processedLine = line;
|
|
if (processedLine.Contains("{datetime}"))
|
|
{
|
|
processedLine = processedLine.Replace("{datetime}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture));
|
|
}
|
|
if (processedLine.Contains("{Part_ident}"))
|
|
{
|
|
processedLine = processedLine.Replace("{Part_ident}", strCarID);
|
|
}
|
|
if (processedLine.Contains("{model}"))
|
|
{
|
|
processedLine = processedLine.Replace("{model}", ConfigDfn.strCarModel);
|
|
}
|
|
if (processedLine.Contains("{Part_code}"))
|
|
{
|
|
if (ConfigDfn.strCarModel == "E03")
|
|
processedLine = processedLine.Replace("{Part_code}", "E03_5000000FAonline");
|
|
else if (ConfigDfn.strCarModel == "E0Y")
|
|
processedLine = processedLine.Replace("{Part_code}", "E0Y_5000000FAonline");
|
|
else
|
|
processedLine = processedLine.Replace("{Part_code}", "UnknownModel_5000000FAonline");
|
|
}
|
|
processedLine = processedLine.Trim('"');
|
|
Console.WriteLine($"处理行: {processedLine}");
|
|
sb.AppendLine(processedLine);
|
|
}
|
|
|
|
// 空行分隔
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
sb.AppendLine();
|
|
|
|
// 添加测量数据表头
|
|
sb.AppendLine("Characteristic,Extension,Measured_Value");
|
|
|
|
// 添加测量数据内容
|
|
foreach (DataRow row in measureData.Rows)
|
|
{
|
|
//sb.AppendFormat("{0},{1},{2}\n",
|
|
// row["PointName"], row["DimensionName"], row["DimensionValue"]);
|
|
|
|
var dimensionValue = row["DimensionValue"]?.ToString();
|
|
if (dimensionValue != null && dimensionValue.Contains("1.#R"))
|
|
{
|
|
dimensionValue = "";
|
|
}
|
|
sb.AppendFormat("{0},{1},{2}\n",
|
|
row["PointName"], row["DimensionName"], dimensionValue);
|
|
|
|
}
|
|
|
|
// 可根据实际需求添加统计行 sb.AppendLine("POP,P,99.99");
|
|
|
|
// 写入文件
|
|
File.WriteAllText(savePath, sb.ToString(), Encoding.UTF8);
|
|
}
|
|
|
|
// 日志记录方法
|
|
private void Trace(string msg)
|
|
{
|
|
OnLog?.Invoke(msg);
|
|
MyBase.TraceWriteLine(msg); // 保持原有日志
|
|
}
|
|
|
|
// 打印 DataTable 对象的方法,输入是对象
|
|
public static void PrintDataTable(DataTable dt)
|
|
{
|
|
if (dt == null || dt.Rows.Count == 0)
|
|
{
|
|
Console.WriteLine("[PrintDataTable] DataTable is empty or null.");
|
|
return;
|
|
}
|
|
foreach (DataColumn column in dt.Columns)
|
|
{
|
|
Console.WriteLine($"{column.ColumnName}\t");
|
|
}
|
|
Console.WriteLine("");
|
|
foreach (DataRow row in dt.Rows)
|
|
{
|
|
foreach (var item in row.ItemArray)
|
|
{
|
|
Console.WriteLine($"{item}\t");
|
|
}
|
|
Console.WriteLine("");
|
|
}
|
|
}
|
|
|
|
// 测试方法
|
|
public void test()
|
|
{
|
|
SQLHelper.connStr = DatabaseDfn.SqlConnectStr();
|
|
//string testPath = @"D:\CJLR\DATA\Input\LLL\K0902906.csv";
|
|
//bool result = MatchCsvValue(testPath, "X540_L", 3, 1);
|
|
//MyBase.TraceWriteLine($"匹配结果: {result}");
|
|
|
|
GenCustomerReport("K0902906");
|
|
}
|
|
}
|
|
} |