using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using CnasSynchronusClient; using CnasSynchrousModel; using CnasSynchronousCommon; using log4net.Repository.Hierarchy; using System.Threading; using System.IO; using Newtonsoft.Json; using System.Diagnostics; namespace CNAS_RunSync { public partial class ucSynchrousMain : UserControl { private string delayDays = FileOperation.GetSystemFormatConfigData().ShowDelayDays; private SyncInstrumentItemInfo syncInstrumentItem = new SyncInstrumentItemInfo(); //private Dictionary dictSourceTables = new Dictionary(); private DataTable dtSource = new DataTable(); //当前显示数据源 private Dictionary dictSource = new Dictionary(); private Dictionary DictComboBox = new Dictionary(); //ComboBox数据源 private List lstIntOrDouble = new List() { "等于", "不等于", "大于", "小于", "不大于", "不小于" }; private List lstText = new List() { "等于", "不等于", "包含", "不包含" }; private Color FinedBackColor = Color.LightCyan; //查询后选中项 Dictionary DictField = new Dictionary(); public ucSynchrousMain() { InitializeComponent(); } //需要存在一个仪器才能正常显示数据 public ucSynchrousMain(SyncInstrumentItemInfo syncInstrumentItem) { InitializeComponent(); dgvSyncData.AutoGenerateColumns = false; dgvSyncData.RowHeadersVisible = false; //dgvSyncData.RowsDefaultCellStyle.BackColor = Color.Bisque; dgvSyncData.AlternatingRowsDefaultCellStyle.BackColor = Color.WhiteSmoke; this.syncInstrumentItem = syncInstrumentItem; } /// /// 控件加载时发生 /// /// /// private void ucSynchrousMain_Load(object sender, EventArgs e) { BindData(); } /// /// 绑定数据 /// public void BindData() { if (this.syncInstrumentItem == null) return; this.lblTitle.Text = string.Format("当前仪器:【{0}】", syncInstrumentItem.Code); if (syncInstrumentItem.LstSyncPramas == null) return; if (syncInstrumentItem.SyncInstrumentDSInfo == null) return; //if (syncInstrumentItem.SyncInstrumentDSInfo.Path == null) return; if (syncInstrumentItem.SyncInstrumentDSInfo.InstrumentDataSourceType == DataSourceType.None) return; this.lblTitleMsg.Text= string.Format("类型:{0} 路径:{1}", syncInstrumentItem.SyncInstrumentDSInfo.InstrumentDataSourceType.ToString(),syncInstrumentItem.SyncInstrumentDSInfo.Path); //清空现有绑定 DictComboBox.Clear(); dictSource.Clear(); //加载相关数据 //1.1根据仪器类型加载本地存储的中英文字段说明映射 //if (syncInstrumentItem.LstSyncPramas.Count > 0) //{ //InstrumentDescribeZH describeZH = new InstrumentDescribeZH(syncInstrumentItem.InstruType, syncInstrumentItem.LstSyncPramas[0].SourceTable); //describeZH.GetFieldDescribe(); //DictField = describeZH.DictField; //} //2.datagridview中绑定数据(绑定的是从数据源中读取的数据) //2.1 根据映射表,创建datagridviewcolumn/和绑定数据列 if (syncInstrumentItem.LstSyncPramas.Count <= 0) return; //创建选择列 AddCheckBoxColumn(dgvSyncData, "selectedColumn", "选择", 80, true); //创建数据列 foreach (var item in syncInstrumentItem.LstSyncPramas) { string strColumnName = item.SourceField; if (DictField.ContainsKey(strColumnName)) strColumnName = DictField[strColumnName]; AddDatagridColumn(dgvSyncData, item.SourceField, strColumnName, 150, bSort: item.IfDateField); } //创建GUID列 AddDatagridColumn(dgvSyncData, "GridGuid", "GridGuid", 50, false); //2.2获取数据源数据 this.RefreshData(); //3.初始化查询相关内容 //3.1 绑定Combobox数据源 foreach (DataColumn dc in dtSource.Columns) { if (syncInstrumentItem.LstSyncPramas.Where(s => s.SourceField == dc.ColumnName.ToUpper()).LongCount() > 0) { string strColumnName = dc.ColumnName.ToUpper(); if (DictField.ContainsKey(strColumnName)) strColumnName = DictField[strColumnName]; DictComboBox.Add(strColumnName, dc.DataType); } } if (DictComboBox.Count > 0) { BindingSource bsComboBox = new BindingSource { DataSource = DictComboBox }; cmbColumns.DataSource = bsComboBox; cmbColumns.ValueMember = "Key"; cmbColumns.DisplayMember = "Key"; } //4.初始化最近上传时间 //4.1 获取目标表最近上传时间 Dictionary times = this.ReadSyncTime(); if (true == times?.ContainsKey(this.syncInstrumentItem.Code)) { this.lblTitleLastUpdateTime.Text = $"最近上传时间:{times[this.syncInstrumentItem.Code]}"; } } /// /// /// private void RefreshData() { //清空现有绑定 dictSource?.Clear(); dtSource?.Clear(); dtSource?.Dispose(); dtSource = null; dgvSyncData?.Rows?.Clear(); //2.2 获取数据源数据,构建datagridviewcell //2.2.1 获取数据源数据 var query = syncInstrumentItem.LstSyncPramas.Where(s => s.IfDateField == true).ToList(); if (query.Count == 1) { object[] obj = new object[] { syncInstrumentItem.LstSyncPramas[0].SourceTable, query[0].SourceField, DateTime.Now.AddDays(Convert.ToInt32(delayDays)).ToString("yyyy-MM-dd HH:mm:ss") }; InstrumentData instrumentData = InstrumentDataFact.CreateInstrumentDataSource(syncInstrumentItem.SyncInstrumentDSInfo, obj); dtSource = instrumentData.GetInstrumentDataByDate(); DataView dv = dtSource.DefaultView; dv.Sort = $"{query[0].SourceField} DESC"; dtSource = dv.ToTable(); } //2.2.2 构建datagridviewcell foreach (DataRow dr in dtSource.Rows) { DataGridViewRow dataGridViewRow = new DataGridViewRow(); foreach (DataGridViewColumn dataGridViewColumn in dgvSyncData.Columns) { if (dataGridViewColumn.Index == 0) { dataGridViewRow.Cells.Add(new DataGridViewCheckBoxCell()); } if (dtSource.Columns.Contains(dataGridViewColumn.Name)) AddDataTextCell(dataGridViewRow, dataGridViewColumn, dr); } //添加GUID值 string strGuid = Guid.NewGuid().ToString(); DataGridViewTextBoxCell txtCell = new DataGridViewTextBoxCell { Value = strGuid }; dataGridViewRow.Cells.Add(txtCell); dgvSyncData.Rows.Add(dataGridViewRow); dictSource.Add(strGuid, dr); } } /// /// 添加datagridview的列 /// /// /// /// /// /// private void AddDatagridColumn(DataGridView dgvShow, string strColumnName, string strColumnHeaderText, int Width, bool bVisible = true, bool bSort = false) { DataGridViewColumn Column = new DataGridViewColumn() { Name = strColumnName, HeaderText = strColumnHeaderText, Width = Width, Visible = bVisible, CellTemplate = new DataGridViewTextBoxCell(), ReadOnly = true, SortMode = bSort ? DataGridViewColumnSortMode.Automatic : DataGridViewColumnSortMode.NotSortable }; //设置文本对齐方式 Column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; Column.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; //设置该列背景颜色 dgvShow.Columns.Add(Column); } private void AddCheckBoxColumn(DataGridView dgvShow, string strColumnName, string strColumnHeaderText, int Width, bool bVisible = true) { DataGridViewCheckBoxColumn selectedColumn = new DataGridViewCheckBoxColumn() { HeaderText = strColumnHeaderText, Name = strColumnName, Visible = bVisible, Width = Width, ReadOnly = false }; //设置文本对齐方式 selectedColumn.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; selectedColumn.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter; //设置该列背景颜色 dgvShow.Columns.Add(selectedColumn); } /// /// 添加datagridview的单元格 /// /// /// /// private void AddDataTextCell(DataGridViewRow dataGridViewRow, DataGridViewColumn dataGridViewColumn, DataRow dr) { DataGridViewTextBoxCell txtCell = new DataGridViewTextBoxCell(); txtCell.Value = Convert.ToString(dr[dataGridViewColumn.Name]); dataGridViewRow.Cells.Add(txtCell); } private void btnRunData_Click(object sender, EventArgs e) { //组织上传数据 if (dgvSyncData.Columns.Count <= 0) return; DataTable dtReadySource = dtSource.Clone(); GetUpLoadData(ref dtReadySource); if (dtReadySource.Rows.Count <= 0) { string strMsg = "未能获得上传数据,请查询筛选后重试!"; MessageBox.Show(strMsg); WriteMsgToRichTextBox(strMsg); } //执行上传 RunUpLoad(dtReadySource); } /// /// 获取上传数据 /// /// 准备上传的数据 private void GetUpLoadData(ref DataTable dtReadySource) { foreach (DataGridViewRow dgvRow in dgvSyncData.Rows) { if (dgvRow.DefaultCellStyle.BackColor == FinedBackColor) { string strGuid = dgvRow.Cells["GridGuid"].Value.ToString(); if (!dictSource.ContainsKey(strGuid)) continue; DataRow dr = dictSource[strGuid]; DataRow drReady = dtReadySource.NewRow(); foreach (DataColumn dc in dtReadySource.Columns) { if (dr.Table.Columns.Contains(dc.ColumnName)) drReady[dc.ColumnName] = dr[dc.ColumnName]; } dtReadySource.Rows.Add(drReady); } } } private void RunUpLoad(DataTable dtReadySource) { //根据映射字段获取准备上传的所有数据 if (dtReadySource == null || dtReadySource.Rows.Count <= 0) return; //构建准备插入的数据 DataTable dtTarget = CnasDataOperationFact.CnasDataOperation().GetCNASTablesStruct(syncInstrumentItem.LstSyncPramas[0].TargetTable, syncInstrumentItem.SyncTargetDBInfo); if (dtTarget.Columns.Count <= 0) { MessageBox.Show("未能成功读取CNAS数据库列,请检查数据库配置。"); WriteMsgToRichTextBox("未能成功读取CNAS数据库列,请检查数据库配置。"); return; } //创建插入操作类 CnasInsertOperation insertOperation = new CnasInsertOperation { syncInstrumentItem = syncInstrumentItem }; //逐行插入数据到内存表 string strErrorMsg = insertOperation.CreateInputData(dtReadySource, ref dtTarget); if (strErrorMsg != "") { MessageBox.Show(strErrorMsg); return; } if (dtTarget.Rows.Count <= 0) { MessageBox.Show("未能获取到符合要求的数据,请检查配置或联系管理员。"); WriteMsgToRichTextBox("未能获取到符合要求的数据,请检查配置或联系管理员。"); return; } //检查数据合法性 insertOperation.CheckInsertDataFormat(dtTarget, ref strErrorMsg); if (strErrorMsg != "") { MessageBox.Show(strErrorMsg); return; } //逐行执行插入内存表数据到数据库中 int ErrorCount = 0; int SuccessCount = 0; int OtherCount = 0; List lstError = new List(); foreach (DataRow dr in dtTarget.Rows) { if (dr[11].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[11]}"); dr[11] = kxjsf(dr[11].ToString()); } if (dr[12].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[12]}"); } if (dr[13].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[13]}"); } if (dr[14].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[14]}"); } if (dr[15].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[15]}"); } if (dr[16].ToString().Length > 1) { AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[16]}"); } dr.AcceptChanges(); int iReturn = CnasDataOperationFact.CnasDataOperation().InsertDataToCNASTable(GlobalCommonOperation.ConvertDataRowToTable(dr), syncInstrumentItem.SyncTargetDBInfo, syncInstrumentItem.LstSyncPramas, syncInstrumentItem.CnasInstrumentColumn, syncInstrumentItem.lstFixedValue); if (iReturn <= 0) //此时出现问题 { if (iReturn == -1) { AppLog.ServiceInfo("数据库连接中断,终止本次上传。"); WriteMsgToRichTextBox("数据库连接中断,终止本次上传。"); break; //此时数据库连接中断,直接跳出循环,结束本次数据同步传输 } else if (iReturn == -2) //等于-2表示插入准备更新时发现数据一致,不再执行 { OtherCount++; } else { ErrorCount++; /*需要转换一下,否则会将整个dt全部写入日志*/ lstError.Add(GlobalCommonOperation.ConvertDataRowToTable(dr).Rows[0]); } } else { SuccessCount++; } } ////判断返回结果 //if (lstError.Count <= 0) //{ // MessageBox.Show("上传完成!"); //} //else //{ // AppLog.Error($"未成功上传的数据如下:{TransConvert.ListToString(lstError)}"); // MessageBox.Show("上传过程中发生异常,存在部分数据未成功上传,请联系管理员!"); //} MessageBox.Show($"上传操作完成!其中成功{SuccessCount}条,失败{ErrorCount}条,其他{OtherCount}条。"); WriteMsgToRichTextBox($"上传操作完成!其中成功{SuccessCount}条,失败{ErrorCount}条,其他{OtherCount}条。"); if (lstError.Count > 0) { AppLog.Error($"未成功上传的数据如下:{TransConvert.ListToString(lstError)}"); WriteMsgToRichTextBox($"未成功上传的数据如下:{TransConvert.ListToString(lstError)}"); } // 记录上传时间 if (0 < SuccessCount) { DateTime time = DateTime.Now; this.lblTitleLastUpdateTime.Text = $"最近上传时间:{time.ToString("yyyy-MM-dd HH:mm:ss")}"; this.WriteSyncTime(time); } } private string kxjsf(string sss) { double sd = Convert.ToDouble(sss); //double sd = 123.123456; string temps2 = "0"; string temps3 = "0"; string temps4 = "0"; int tempi2 = 0; int tempi3 = 0; int tempi4 = 0; if (sss.Contains('.')) { string[] s1 = sss.Split('.'); if (s1[1].Length > 2) { if (s1[1].Length > 2) { temps2 = s1[1].Substring(1, 1); temps3 = s1[1].Substring(2, 1); } tempi2 = int.Parse(temps2); tempi3 = int.Parse(temps3); if (s1[1].Length > 3) { temps4 = s1[1].Substring(3, 1); } tempi4 = int.Parse(temps4); if (tempi3 > 5 || tempi3 < 5) { return sd.ToString("0.00"); } else { if (tempi4 != 0) { return sd.ToString("0.00"); } else { if (tempi2 == 0 || tempi2 == 2 || tempi2 == 4 || tempi2 == 6 || tempi2 == 8) { return sss.Substring(0, 5); } else { return sd.ToString("0.00"); } } } } } return sss; } private void cmbColumns_SelectedIndexChanged(object sender, EventArgs e) { if (cmbColumns.SelectedItem == null) return; KeyValuePair obj = (KeyValuePair)cmbColumns.SelectedItem; if (DictComboBox.ContainsKey(obj.Key)) { Type selectType = DictComboBox[obj.Key]; switch (selectType.ToString()) { case "System.DateTime": UseDateTimeControl(); break; case "System.Double": case "System.Int64": case "System.Int32": UseNormalControl(); //绑定条件ComboBox combCondition.DataSource = lstIntOrDouble; break; case "System.Byte[]": case "System.String": default: UseNormalControl(); //绑定条件ComboBox combCondition.DataSource = lstText; break; } } } /// /// 使用时间类型专用的查询控件组 /// private void UseDateTimeControl() { if (pnlCheck.Controls.Contains(pnlText)) pnlCheck.Controls.Remove(pnlText); if (!pnlCheck.Controls.Contains(pnlDate)) { pnlCheck.Controls.Add(pnlDate); pnlDate.Visible = true; pnlDate.Dock = DockStyle.Fill; } } /// /// 使用标准的查询控件组 /// private void UseNormalControl() { if (pnlCheck.Controls.Contains(pnlDate)) pnlCheck.Controls.Remove(pnlDate); if (!pnlCheck.Controls.Contains(pnlText)) { pnlCheck.Controls.Add(pnlText); pnlText.Visible = true; pnlText.Dock = DockStyle.Fill; } } private void btnFind_Click(object sender, EventArgs e) { if (cmbColumns.SelectedValue == null) { return; } //0.获取数据源数据 this.RefreshData(); //1.合法性检测 if (DictComboBox[cmbColumns.SelectedValue.ToString()].ToString().Equals("System.DateTime")) { if (dtpTarget.Value < dtpSource.Value) { MessageBox.Show("查询时间需要一个有效的时间范围!"); return; } } else { if (this.txtFind.Text.Trim() == "") //为空 认为是取消查询 { btnCancelFind_Click(sender, e); return; } } //2.将datagridview中满足条件的项修改背景色 //2.1 判断当前显示的datagridview是否含有旧的查询数据 //2.2 将满足条件的项背景色改为特殊颜色 for (int index = dgvSyncData.Rows.Count - 1; 0 <= index; --index) { DataGridViewRow row = dgvSyncData.Rows[index]; //查询列的当前值 string strGuid = row.Cells["GridGuid"].Value.ToString(); if (DictField.Count > 0) { var query = DictField.Where(s => s.Value == cmbColumns.SelectedValue.ToString()); if (query.Count() == 1) { string strValue = row.Cells[query.ElementAtOrDefault(0).Key].Value.ToString(); //判断是否满足条件 if (false == CheckMatchCondition(strValue)) { dgvSyncData.Rows.RemoveAt(index); } } } else { string strValue = row.Cells[cmbColumns.SelectedValue.ToString()].Value.ToString(); //判断是否满足条件 if (false == CheckMatchCondition(strValue)) { dgvSyncData.Rows.RemoveAt(index); } } } } private bool CheckMatchCondition(string strValue) { if (DictComboBox[cmbColumns.SelectedValue.ToString()].ToString().Equals("System.DateTime")) { DateTime dt = DateTime.Now; if (!DateTime.TryParse(strValue, out dt)) return false; DateTime dtSource = dtpSource.Value; DateTime dtTarget = dtpTarget.Value; DateTime dtValue = dt; if (dt >= dtSource && dt <= dtTarget) return true; else return false; } else { string strFindText = this.txtFind.Text.ToString(); bool bReturn = false; try { switch (combCondition.SelectedValue.ToString()) { case "等于": bReturn = strValue == strFindText ? true : false; break; case "不等于": bReturn = strValue != strFindText ? true : false; break; case "包含": bReturn = strValue.Contains(strFindText) ? true : false; break; case "不包含": bReturn = !strValue.Contains(strFindText) ? true : false; break; case "大于": bReturn = Convert.ToDouble(strValue) > Convert.ToDouble(strFindText) ? true : false; break; case "不小于": bReturn = Convert.ToDouble(strValue) >= Convert.ToDouble(strFindText) ? true : false; break; case "小于": bReturn = Convert.ToDouble(strValue) < Convert.ToDouble(strFindText) ? true : false; break; case "不大于": bReturn = Convert.ToDouble(strValue) <= Convert.ToDouble(strFindText) ? true : false; break; } } catch (Exception ex) { AppLog.Error(ex.Message); bReturn = false; } return bReturn; } } /// /// 获得查询语句(非日期类型) /// /// /// /// /// /// private string GetSelectString(string strColumnName, string strCondition, string strValue) { string strCondi = ""; switch (strCondition) { case "等于": strCondi = "="; break; case "不等于": strCondi = "<>"; break; case "包含": strCondi = "like"; break; case "不包含": strCondi = "not like"; break; case "大于": strCondi = ">"; break; case "不小于": strCondi = ">="; break; case "小于": strCondi = "<"; break; case "不大于": strCondi = "<="; break; } if (strCondi == "like" || strCondi == "not like") return string.Format("{0} {1} '%{2}%'", strColumnName, strCondi, strValue); else return string.Format("{0} {1} '{2}'", strColumnName, strCondi, strValue); } private void btnCancelFind_Click(object sender, EventArgs e) { foreach (DataGridViewRow dgvrow in dgvSyncData.Rows) { if (dgvrow.Cells[0].Value != null && dgvrow.Cells[0].Value.ToString() == "True") dgvrow.Cells[0].Value = false; if (dgvrow.Index % 2 == 1) { dgvrow.DefaultCellStyle.BackColor = Color.WhiteSmoke; } else { dgvrow.DefaultCellStyle.BackColor = Color.White; } } } private void dgvSyncData_CellValueChanged(object sender, DataGridViewCellEventArgs e) { //只有第一列“选择列”时触发 if (e.ColumnIndex == 0) { if (dgvSyncData.Rows[e.RowIndex].Cells[0].Value.ToString() == "True") dgvSyncData.Rows[e.RowIndex].DefaultCellStyle.BackColor = FinedBackColor; else { if (e.RowIndex % 2 == 1) { dgvSyncData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.WhiteSmoke; } else { dgvSyncData.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.White; } } } } public void WriteMsgToRichTextBox(string strMsg) { Invoke(new MethodInvoker(delegate () { this.rtxtLog.Text += string.Format("{0} 日期: {1}\n", strMsg,DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")); })); } /// /// /// /// private void WriteSyncTime(DateTime time) { try { /* 创建文件夹 */ string logDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache"); if (!Directory.Exists(logDirectory)) { Directory.CreateDirectory(logDirectory); } /* 更新时间 */ string file = Path.Combine(logDirectory, $"SyncTime.bin"); Dictionary times = this.ReadSyncTime() ?? new Dictionary(); if (true == times.ContainsKey(this.syncInstrumentItem.Code)) { times[this.syncInstrumentItem.Code] = time.ToString("yyyy-MM-dd HH:mm:ss"); } else { times.Add(this.syncInstrumentItem.Code, time.ToString("yyyy-MM-dd HH:mm:ss")); } /* 写入文件 */ File.WriteAllText(file, JsonConvert.SerializeObject(times, Formatting.Indented)); } catch (Exception exception) { Invoke(new MethodInvoker(delegate () { this.rtxtLog.Text += $"记录同步时间出错!错误信息:{exception.Message} 日期: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}\n"; })); } } /// /// /// private Dictionary ReadSyncTime() { Dictionary times = null; if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache", $"SyncTime.bin"))) { try { using (StreamReader reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache", $"SyncTime.bin"), Encoding.UTF8)) { try { string json = reader.ReadToEnd(); times = JsonConvert.DeserializeObject>(json); } catch { } finally { reader.Close(); reader.Dispose(); } } } catch (Exception exception) { Debug.WriteLine(exception.Message); } } return times; } } }