using CnasSynchronousCommon;
using CnasSynchrousModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Management;
using System.Net.NetworkInformation;
using System.Text;
using System.Text.RegularExpressions;
namespace CnasSynchronusClient
{
public class CnasInsertOperation
{
///
/// 同步配置信息
///
public SyncInstrumentItemInfo syncInstrumentItem { get; set; }
///
/// 创建准备插入到CNAS的数据
///
///
///
///
public string CreateInputData(DataTable dtReadySource, ref DataTable dtTarget)
{
string strErrorMsg = "";
string strDateColumn = "";
try
{
//获取日期字段
strDateColumn = GetDateFieldOperation(ref strErrorMsg);
if (strErrorMsg != "") return strErrorMsg;
//新数据行的创建和插入数据
foreach (DataRow drSource in dtReadySource.Rows)
{
DataRow drNewTarget = dtTarget.NewRow();
//根据过滤器执行来源数据过滤
AppLog.Info("过滤检测");
if (!SourceDataFilterOperation(drSource)) continue;
//根据映射字段尝试塞入数据到数据行,排除不合法数据。
AppLog.Info("合法性检测");
NormalParamsValueInsertOperation(dtReadySource, dtTarget, drSource, drNewTarget, strDateColumn, ref strErrorMsg);
if (strErrorMsg != "") break;
//根据固定值字段塞入数据到数据行
AppLog.Info("条件映射数据更改");
FixConditonParamsInsertOperation(dtReadySource, dtTarget, drSource, drNewTarget);
//补充仪器信息数据
AppLog.Info("补充仪器信息数据");
if (syncInstrumentItem.CnasInstrumentColumn == null)
{
strErrorMsg = "未设置的CNAS仪器信息列,请先配置";
break;
}
// 使用实际的机器码来验证
if (dtTarget.Columns.Contains(syncInstrumentItem.CnasInstrumentColumn))
drNewTarget[syncInstrumentItem.CnasInstrumentColumn] = syncInstrumentItem.GUID + "@" + GenerateActivationCode(GetMachineCode());
else
{
strErrorMsg = "设置的CNAS仪器信息列没有在库中找到,请重新配置";
break;
}
//塞入数据的数据行包含到dt中
dtTarget.Rows.Add(drNewTarget);
}
AppLog.Info("构造数据行循环结束");
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
strErrorMsg = ex.Message;
}
return strErrorMsg;
}
private string GenerateActivationCode(string machineCode)
{
// 这里实现激活码生成算法
// 示例:简单的加密算法,实际应用中应该使用更安全的加密方式
using (var md5 = System.Security.Cryptography.MD5.Create())
{
// 加入时间戳使得生成的激活码具有时效性
string input = machineCode + DateTime.Now.ToString("yyyyMMdd");
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// 转换为16进制字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
// 每4个字符添加一个分隔符,提高可读性
if ((i + 1) % 4 == 0 && i != hashBytes.Length - 1)
{
sb.Append("-");
}
}
return sb.ToString();
}
}
private string GetMachineCode()
{
StringBuilder machineCode = new StringBuilder();
// 获取CPU ID
string cpuId = GetCPUId();
machineCode.Append(cpuId);
// 获取所有MAC地址
List macAddresses = GetMACAddresses();
foreach (string mac in macAddresses)
{
machineCode.Append("_").Append(mac);
}
return machineCode.ToString();
}
private string GetCPUId()
{
try
{
using (ManagementClass mc = new ManagementClass("Win32_Processor"))
{
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
return mo.Properties["ProcessorId"].Value.ToString();
}
}
}
catch (Exception ex)
{
throw new Exception("获取CPU ID失败: " + ex.Message);
}
return string.Empty;
}
private List GetMACAddresses()
{
List macAddresses = new List();
try
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface adapter in nics)
{
// 只获取物理网卡的MAC地址
if (adapter.NetworkInterfaceType == NetworkInterfaceType.Ethernet ||
adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
{
string mac = adapter.GetPhysicalAddress().ToString();
if (!string.IsNullOrEmpty(mac))
{
macAddresses.Add(mac);
}
}
}
}
catch (Exception ex)
{
throw new Exception("获取MAC地址失败: " + ex.Message);
}
return macAddresses;
}
///
/// 获取日期字段
///
///
///
private string GetDateFieldOperation(ref string strErrorMsg)
{
string strDateColumn = "";
var query = syncInstrumentItem.LstSyncPramas.Where(s => s.IfDateField == true).ToList();
if (query.Count != 1)
{
strErrorMsg = "创建CNAS数据行失败,未找到日期字段。";
}
else
{
strDateColumn = query[0].TargetField;
}
return strDateColumn;
}
///
/// 普通值(非固定值)插入操作
///
///
///
///
///
///
///
private void NormalParamsValueInsertOperation(DataTable dtReadySource, DataTable dtTarget, DataRow drSource, DataRow drNewTarget, string strDateField, ref string strErrorMsg)
{
foreach (var item in syncInstrumentItem.LstSyncPramas)
{
var strSourceField = item.SourceField;
var strTargetField = item.TargetField;
//当列名存在于数据表中时才能继续
if (dtReadySource.Columns.Contains(strSourceField) && dtTarget.Columns.Contains(strTargetField))
{
strErrorMsg = TestConvertValueToTarget(drNewTarget, drSource, strTargetField, strSourceField, strDateField);
if (strErrorMsg != "")
{
strErrorMsg = string.Format("发生数据转换错误,请重新配置映射字段或修改字段值。错误信息如下:列【{0}】,值【{1}】,详情【{2}】", strSourceField, drSource[strSourceField].ToString(), strErrorMsg);
break;
}
}
}
}
///
/// 固定值插入数据操作
///
///
///
///
///
public void FixConditonParamsInsertOperation(DataTable dtReadySource, DataTable dtTarget, DataRow drSource, DataRow drNewTarget)
{
try
{
foreach (var item in syncInstrumentItem.lstFixedValue)
{
if (dtTarget.Columns.Contains(item.ColumnName))
{
switch (item.Condition)
{
case MapCondition.Equal:
drNewTarget[item.ColumnName] = item.Value;
break;
case MapCondition.Sub:
ChangeSubConditionValue(item, dtReadySource, drSource, drNewTarget);
break;
case MapCondition.IFThen:
ChangeIFThenConditionValue(item, dtReadySource, drSource, drNewTarget);
break;
case MapCondition.SubString:
ChangeSubStringConditonValue(item, drNewTarget);
break;
case MapCondition.SubstringStartEnd:
ChangeStartEndSubStringConditonValue(item, drNewTarget);
break;
case MapCondition.Divided:
double db1, db2;
if (double.TryParse(drNewTarget[item.ColumnName].ToString(), out db1))
{
string[] slist = item.Value.ToString().Split(',');
if (slist.Length > 1)
{
drNewTarget[item.ColumnName] = Math.Round(db1 / Convert.ToDouble(slist[0].ToString()), Convert.ToInt32(slist[1]));
//if (double.TryParse(item.Value.ToString(), out db2))
// = db1 / db2;
}
}
break;
case MapCondition.Multiplied:
double db3, db4;
if (double.TryParse(drNewTarget[item.ColumnName].ToString(), out db3))
{
string[] slist = item.Value.ToString().Split(',');
if (slist.Length > 1)
{ drNewTarget[item.ColumnName] = Math.Round(db3 * Convert.ToDouble(slist[0].ToString()), Convert.ToInt32(slist[1])); }
}
break;
case MapCondition.DecimalDigits:
double db5;
int count;
if (double.TryParse(drNewTarget[item.ColumnName].ToString(), out db5))
{
if (int.TryParse(item.Value.ToString(), out count))
drNewTarget[item.ColumnName] = Math.Round(db5, count);
}
break;
case MapCondition.AddSubtract:
ChangeAddSubtractConditonValue(syncInstrumentItem.lstFixedValue, item, dtReadySource, drSource, drNewTarget);
break;
}
}
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
private void ChangeStartEndSubStringConditonValue(CnasConditionMapValue item, DataRow drNewTarget)
{
try
{
if (item.Value != null && item.Value.ToString() != "")
{
string[] strValues = item.Value.ToString().Split(new string[] { "{", ",", "}" }, StringSplitOptions.RemoveEmptyEntries);
if (strValues.Length == 2)
{
string[] strConfigValues = strValues[0].Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
if (strValues[1] == "S")
{
//Regex reg = new Regex($"^[{strValues[0]}]");
//if (reg.IsMatch(drNewTarget[item.ColumnName].ToString()))
// drNewTarget[item.ColumnName] = drNewTarget[item.ColumnName].ToString().(0, drNewTarget[item.ColumnName].ToString().Length - 1);
foreach (string strConfigValue in strConfigValues)
{
if (drNewTarget[item.ColumnName].ToString().StartsWith(strConfigValue))
{
drNewTarget[item.ColumnName] = drNewTarget[item.ColumnName].ToString().Substring(strConfigValue.Length, drNewTarget[item.ColumnName].ToString().Length - strConfigValue.Length);
break;
}
}
}
else if (strValues[1] == "E")
{
//Regex reg = new Regex($"[{strValues[0]}]$");
//if (reg.IsMatch(drNewTarget[item.ColumnName].ToString()))
// drNewTarget[item.ColumnName] = drNewTarget[item.ColumnName].ToString().Substring(0, drNewTarget[item.ColumnName].ToString().Length-1);
foreach (string strConfigValue in strConfigValues)
{
if (drNewTarget[item.ColumnName].ToString().EndsWith(strConfigValue))
{
drNewTarget[item.ColumnName] = drNewTarget[item.ColumnName].ToString().Substring(0, drNewTarget[item.ColumnName].ToString().Length - strConfigValue.Length);
break;
}
}
}
}
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
///
/// 处理SUB类型固定值
///
///
///
///
///
private void ChangeSubConditionValue(CnasConditionMapValue item, DataTable dtReadySource, DataRow drSource, DataRow drNewTarget)
{
try
{
//解析Value值,如果不能解析,直接插入Value值
if (item.Value != null && item.Value.ToString() != "")
{
string strInputValue = "";
string[] strValues = item.Value.ToString().Split(new string[] { "+" }, StringSplitOptions.RemoveEmptyEntries);
if (strValues.Length >= 1 && strValues.Length <= 3)
{
switch (strValues.Length)
{
case 1:
string strColumnName1 = strValues[0].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName1))
strInputValue = drSource[strColumnName1].ToString();
else
strInputValue = strValues[0];
break;
case 2:
strColumnName1 = strValues[0].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName1))
strInputValue = drSource[strColumnName1].ToString();
else
strInputValue = strValues[0];
string strColumnName2 = strValues[1].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName2))
strInputValue += drSource[strColumnName2].ToString();
else
strInputValue += strValues[1];
break;
case 3:
strColumnName1 = strValues[0].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName1))
strInputValue = drSource[strColumnName1].ToString();
else
strInputValue = strValues[0];
strColumnName2 = strValues[1].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName2))
strInputValue += drSource[strColumnName2].ToString();
else
strInputValue += strValues[1];
string strColumnName3 = strValues[2].Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries)[0];
if (dtReadySource.Columns.Contains(strColumnName3))
strInputValue += drSource[strColumnName3].ToString();
else
strInputValue += strValues[2];
break;
}
}
else
{
strInputValue = item.Value.ToString();
}
drNewTarget[item.ColumnName] = strInputValue;
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
private bool SourceDataFilterOperation(DataRow dr)
{
//如果过滤器为空或没有任何条件,我们认为用户允许所有数据通过过滤审核
if (syncInstrumentItem.SourceFilter == null) return true;
if (syncInstrumentItem.SourceFilter.lstFilterConditions == null) return true;
if (syncInstrumentItem.SourceFilter.lstFilterConditions.Count == 0) return true;
bool bReturn = false;
try
{
List lstMatch = new List();
foreach (FilterCondition item in syncInstrumentItem.SourceFilter.lstFilterConditions)
{
bool bIsMatch = false;
string strConditionValue = item.ConditionValue;
if (strConditionValue == null) continue;
if (strConditionValue.StartsWith("RegEx")) //此时使用正则表达式匹配
{
string[] strRegExs = strConditionValue.Split(new string[] { "RegEx:" }, StringSplitOptions.RemoveEmptyEntries);
if (strRegExs.Length != 1) continue;
bIsMatch = Regex.IsMatch(dr[item.ColumnName].ToString(), strRegExs[0]);
}
else
{
double result;
double conditionresult;
switch (item.Algorithm)
{
case "=":
bIsMatch = dr[item.ColumnName].ToString() == item.ConditionValue ? true : false;
break;
case "<>":
bIsMatch = dr[item.ColumnName].ToString() == item.ConditionValue ? false : true;
break;
case "like":
bIsMatch = dr[item.ColumnName].ToString().Contains(item.ConditionValue) ? true : false;
break;
case "not like":
bIsMatch = dr[item.ColumnName].ToString().Contains(item.ConditionValue) ? false : true;
break;
case ">":
if (dr[item.ColumnName] != null)
if (double.TryParse(dr[item.ColumnName].ToString(), out result) && double.TryParse(item.ConditionValue, out conditionresult))
bIsMatch = result > conditionresult ? true : false;
break;
case "<":
if (dr[item.ColumnName] != null)
if (double.TryParse(dr[item.ColumnName].ToString(), out result) && double.TryParse(item.ConditionValue, out conditionresult))
bIsMatch = result < conditionresult ? true : false;
break;
case ">=":
if (dr[item.ColumnName] != null)
if (double.TryParse(dr[item.ColumnName].ToString(), out result) && double.TryParse(item.ConditionValue, out conditionresult))
bIsMatch = result >= conditionresult ? true : false;
break;
case "<=":
if (dr[item.ColumnName] != null)
if (double.TryParse(dr[item.ColumnName].ToString(), out result) && double.TryParse(item.ConditionValue, out conditionresult))
bIsMatch = result <= conditionresult ? true : false;
break;
}
}
lstMatch.Add(bIsMatch);
}
if (syncInstrumentItem.SourceFilter.FilterConditionLinkType == "and")
{
//只要有一个为否,则返回否
if (lstMatch.Where(x => x.Equals(false)).Count() > 0)
bReturn = false;
else
bReturn = true;
}
else
{
//只要有一个为是,则返回是
if (lstMatch.Where(x => x.Equals(true)).Count() > 0)
bReturn = true;
else
bReturn = false;
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
return bReturn;
}
///
/// 处理IFThen类型固定值
///
///
///
///
///
private void ChangeIFThenConditionValue(CnasConditionMapValue item, DataTable dtReadySource, DataRow drSource, DataRow drNewTarget)
{
try
{
if (item.Value != null && item.Value.ToString() != "")
{
List lstParams = GlobalCommonOperation.AnanlysisIFThenString(item.Value.ToString());
if (lstParams.Count > 0)
{
foreach (var conditionparams in lstParams)
{
if (!dtReadySource.Columns.Contains(conditionparams.ConditionColumnName)) continue;
if (drSource[conditionparams.ConditionColumnName].ToString() == conditionparams.ConditionColumnValue)
drNewTarget[item.ColumnName] = conditionparams.ColumnValue;
}
}
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
///
/// 处理SubString类型固定值
///
///
///
///
///
private void ChangeSubStringConditonValue(CnasConditionMapValue item, DataRow drNewTarget)
{
try
{
if (item.Value != null && item.Value.ToString() != "")
{
string[] strValues = item.Value.ToString().Split(new string[] { "{", ",", "}" }, StringSplitOptions.RemoveEmptyEntries);
if (strValues.Length == 2)
{
string[] strInputValues = drNewTarget[item.ColumnName].ToString().Split(new string[] { strValues[0] }, StringSplitOptions.RemoveEmptyEntries);
if (strInputValues.Length == 1)
{
var list = strInputValues[0].Substring(Convert.ToInt32(strValues[0]), Convert.ToInt32(strValues[1]));
drNewTarget[item.ColumnName] = list;
}
//if (strInputValues.Length == 2) //只处理分割后有两部分的
//{
// if (strValues[1] == "L")
// {
// drNewTarget[item.ColumnName] = strInputValues[0];
// }
// else if (strValues[1] == "R")
// {
// drNewTarget[item.ColumnName] = strInputValues[1];
// }
//}
}
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
private void ChangeAddSubtractConditonValue(List lstConditionMaps, CnasConditionMapValue item, DataTable dtReadySource, DataRow drSource, DataRow drNewTarget)
{
try
{
if (item.Value != null && item.Value.ToString() != "")
{
string[] strValues = item.Value.ToString().Split(new string[] { "{", "}" }, StringSplitOptions.RemoveEmptyEntries);
if (strValues.Length == 3)
{
string strParam1 = strValues[0];
string strParam2 = strValues[2];
double db1, db2;
string[] strParam1s = strParam1.Split(new string[] { "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
if (strParam1s.Length >= 1)
{
string[] strParam2s = strParam2.Split(new string[] { "[", "]" }, StringSplitOptions.RemoveEmptyEntries);
if (strParam2s.Length >= 1)
{
if (dtReadySource.Columns.Contains(strParam1s[0]) && dtReadySource.Columns.Contains(strParam2s[0]))
if (double.TryParse(drSource[strParam1s[0]].ToString(), out db1))
{
if (double.TryParse(drSource[strParam2s[0]].ToString(), out db2))
{
if (strParam1s.Length == 3)
db1 = GetDividedMultipliedData(db1, strParam1s[1], strParam1s[2]);
if (strParam2s.Length == 3)
db2 = GetDividedMultipliedData(db2, strParam2s[1], strParam2s[2]);
drNewTarget[item.ColumnName] = strValues[1].ToLower() == "subtract" ? db1 - db2 : db1 + db2;
}
}
}
}
}
}
}
catch (Exception ex)
{
AppLog.Error(ex.Message);
}
}
///
/// 在计算数值相加和相减之前,如果计算的列已经有乘以或除以的操作,则先进行乘以或除以,再进行相加或相减
///
///
///
///
///
///
public double GetDividedMultipliedData(double db1, string strExpresstion, string strValue)
{
double db2;
if (double.TryParse(strValue, out db2))
{
db1 = strExpresstion == "*" ? db1 * db2 : db1 / db2;
}
return db1;
}
///
/// 对准备插入的数据进行格式上的检查
///
///
///
public void CheckInsertDataFormat(DataTable dtTarget, ref string strErrorMsg)
{
//检查数据合法性
CnasDataCheck check = new CnasDataCheck
{
DtReadyInsert = dtTarget,
TargetDataBase = syncInstrumentItem.SyncTargetDBInfo,
StrTableName = syncInstrumentItem.LstSyncPramas[0].TargetTable
};
check.CheckData();
if (check.LstIllegalMsg != null && check.LstIllegalMsg.Count > 0)
{
var item = syncInstrumentItem.LstSyncPramas.Where(s => s.TargetField == check.LstIllegalMsg[0].ColumnName).ToList();
if (item.Count == 1)
{
strErrorMsg = string.Format("数据不满足上传条件,请修改后再上传。错误数据:当前列名【{0}】,列值【{1}】", item[0].SourceField, check.LstIllegalMsg[0].ColumnValue);
}
else
{
strErrorMsg = string.Format("数据不满足上传条件,请修改后再上传。错误数据:CNAS列名【{0}】,列值【{1}】", check.LstIllegalMsg[0].ColumnName, check.LstIllegalMsg[0].ColumnValue);
}
return;
}
}
///
/// 尝试将值插入到目标表单的各个行中
///
///
private string TestConvertValueToTarget(DataRow drTarget, DataRow drSource, string strTargetColumn, string strSourceColumn, string strDateColumn)
{
string strErrorMsg = "";
try
{
if (strTargetColumn.ToLower() != strDateColumn.ToLower())
{
string strTargetColumnType = drTarget.Table.Columns[strTargetColumn].DataType.ToString();
switch (strTargetColumnType)
{
case "System.Decimal":
if (drSource[strSourceColumn] == null || (drSource[strSourceColumn] != null && drSource[strSourceColumn].ToString() == ""))
drTarget[strTargetColumn] = 0;
else
drTarget[strTargetColumn] = Convert.ToDouble(drSource[strSourceColumn]);
break;
default:
drTarget[strTargetColumn] = drSource[strSourceColumn];
break;
}
}
else //日期字段需要单独处理
{
DateTime dt = DateTime.Now;
if (DateTime.TryParse(drSource[strSourceColumn].ToString(), out dt))
{
drTarget[strTargetColumn] = dt.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
drTarget[strTargetColumn] = drSource[strSourceColumn];
}
}
}
catch (Exception ex)
{
strErrorMsg = ex.Message;
}
return strErrorMsg;
}
}
}