CNAS取数仪器端升级
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

418 líneas
17KB

  1. using CnasSynchronousCommon;
  2. using CnasSynchronusClient;
  3. using CnasSynchrousModel;
  4. using Newtonsoft.Json;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Data;
  8. using System.Diagnostics;
  9. using System.IO;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Timers;
  13. using System.Xml.Serialization;
  14. namespace CNAS_SyncService
  15. {
  16. public class SyncServiceOperation
  17. {
  18. System.Timers.Timer timerSync;
  19. ServiceConfig config = new ServiceConfig();
  20. bool bRunComplete = true;
  21. int WaitCount = 0;
  22. string strNowDate = "";
  23. FileWatcherOperation fileWatcherOperation;
  24. public void Start()
  25. {
  26. AppLog.ServiceInfo("SyncSerivce:服务启动");
  27. //读取全局配置信息
  28. SystemFormatConfig systemFormat = FileOperation.GetSystemFormatConfigData();
  29. GlobalCommonOperation.strStartGeneralVersion = systemFormat.StartGeneralVersion;
  30. GlobalCommonOperation.strStartWebApi = systemFormat.StartWebApi;
  31. GlobalCommonOperation.strWebApiUrl = systemFormat.WebApiUrl;
  32. GlobalCommonOperation.strTargetDbType = systemFormat.TargetDBType;
  33. //读取服务配置信息
  34. config = ReadServiceConfigData();
  35. AppLog.Error("打印日志1" + config.Minutes);
  36. timerSync_Elapsed(null, null);
  37. return;
  38. if (config.Minutes != 0)
  39. {
  40. //启动文件/文件夹监控
  41. if (config.IfStartFileWatcher == "1")
  42. {
  43. fileWatcherOperation = new FileWatcherOperation(ReadSyncInstruments());
  44. fileWatcherOperation.GetFileWatcherItems();
  45. fileWatcherOperation.StartFileWatcher();
  46. }
  47. // 启动定时器
  48. timerSync = new System.Timers.Timer();
  49. timerSync.Interval = config.Minutes * 60 * 1000; //设置计时器事件间隔执行时间
  50. timerSync.Elapsed += new System.Timers.ElapsedEventHandler(timerSync_Elapsed);
  51. timerSync.Enabled = true;
  52. timerSync.AutoReset = true;
  53. }
  54. else
  55. {
  56. //写入日志
  57. AppLog.ServiceInfo("SyncSerivce:未能成功读取定时器时间,本次同步失败。");
  58. }
  59. }
  60. private void timerSync_Elapsed(object sender, ElapsedEventArgs e)
  61. {
  62. AppLog.ServiceInfo("定时器启动");
  63. //如果等待执行次数超出最大数值,则认为当前正在执行出现未知名问题,直接回收当前执行,执行下次
  64. if (WaitCount >= config.MaxWaitCount)
  65. {
  66. //回收垃圾
  67. GC.Collect();
  68. bRunComplete = true;
  69. }
  70. if (bRunComplete)
  71. {
  72. WaitCount = 0; //只要正常执行,等待标识都将恢复为0
  73. bRunComplete = false;
  74. //清理过期日志
  75. if (strNowDate != DateTime.Now.ToString("yyyyMMdd"))
  76. {
  77. AppLog.ServiceInfo("清理过期日志");
  78. strNowDate = DateTime.Now.ToString("yyyyMMdd");
  79. //删除日志文件
  80. string logDays = FileOperation.GetSystemFormatConfigData().ShowLogDays;
  81. int logday;
  82. if (int.TryParse(logDays, out logday))
  83. AppLog.DeleteLog(logday);
  84. }
  85. //执行同步程序
  86. //1.读取配置信息
  87. List<SyncInstrumentItemInfo> lstSyncInstrument = ReadSyncInstruments();
  88. //2 遍历仪器列表,逐个列表进行同步
  89. foreach (var instrumentItem in lstSyncInstrument)
  90. {
  91. //如果是文件,使用FileSystemWatcher查看文件是否发生了变化
  92. if (fileWatcherOperation != null && fileWatcherOperation.LstWatcherItems.Count > 0)
  93. {
  94. var watcherItem = fileWatcherOperation.LstWatcherItems.Where(p => p.SyncItemId == instrumentItem.GUID && p.SyncIfChanged == true).FirstOrDefault();
  95. if (watcherItem != null)
  96. {
  97. RunSyncByInstrument(instrumentItem, watcherItem);
  98. }
  99. else
  100. {
  101. AppLog.ServiceInfo("检测到文件/文件夹没有发生变化,跳过本次同步执行");
  102. }
  103. }
  104. else
  105. {
  106. RunSyncByInstrument(instrumentItem);
  107. }
  108. }
  109. bRunComplete = true;
  110. //回收垃圾
  111. GC.Collect();
  112. }
  113. else
  114. {
  115. WaitCount++;
  116. AppLog.ServiceInfo($"等待标识:{WaitCount}");
  117. }
  118. }
  119. private List<SyncInstrumentItemInfo> ReadSyncInstruments()
  120. {
  121. List<SyncInstrumentItemInfo> lstSyncInstrument = new List<SyncInstrumentItemInfo>();
  122. lstSyncInstrument = FileOperation.GetLocalSyncInStrumentData();
  123. AppLog.ServiceInfo($"读取到本地配置信息行数{lstSyncInstrument.Count}");
  124. return lstSyncInstrument;
  125. }
  126. private void RunSyncByInstrument(SyncInstrumentItemInfo syncInstrumentItem, FileWatcherItem fileWatcherItem = null)
  127. {
  128. //0.读取目标库表数据的最大时间 1.读取来源的数据 2.对读取到的数据进行逻辑处理,整理格式 3.执行同步
  129. AppLog.ServiceInfo("准备根据日期字段查询筛选");
  130. var query = syncInstrumentItem.LstSyncPramas.Where(s => s.IfDateField == true).ToList<SyncParamasInfo>();
  131. if (query.Count == 1)
  132. {
  133. string strCompareTime = "";
  134. string strDateTime = "";
  135. Dictionary<string, string> times = this.ReadSyncTime();
  136. if (true == times?.ContainsKey(syncInstrumentItem.Code))
  137. {
  138. strDateTime = $"{times[syncInstrumentItem.Code]}";
  139. }
  140. //strDateTime = "2016-07-01 00:00:00";
  141. if (strDateTime == "1899-1-1")
  142. {
  143. AppLog.ServiceInfo($"读取上次最晚执行时间失败,请检查原因。");
  144. return;
  145. }
  146. else if (strDateTime == "")
  147. {
  148. strCompareTime = Convert.ToDateTime(config.InitalDT.ToString()).ToString("yyyy-MM-dd HH:mm:ss");
  149. }
  150. else
  151. strCompareTime = Convert.ToDateTime(strDateTime).AddDays(-3).ToString("yyyy-MM-dd HH:mm:ss");
  152. AppLog.ServiceInfo($"读取上次最晚执行时间为{strCompareTime}");
  153. object[] obj = new object[]
  154. {
  155. syncInstrumentItem.LstSyncPramas[0].SourceTable,
  156. query[0].SourceField,
  157. strCompareTime
  158. };
  159. AppLog.ServiceInfo($"准备构建数据源读取工厂");
  160. InstrumentData instrumentData = InstrumentDataFact.CreateInstrumentDataSource(syncInstrumentItem.SyncInstrumentDSInfo, obj);
  161. AppLog.ServiceInfo($"构建数据源读取工厂完成,准备读取数据源");
  162. DataTable dtReadySource = instrumentData.GetInstrumentDataByDate();
  163. AppLog.ServiceInfo($"根据日期读取准备插入的来源数据,共{dtReadySource.Rows.Count}条数据");
  164. string strErrorMsg = "";
  165. RunUpLoad(syncInstrumentItem, dtReadySource, ref strErrorMsg);
  166. if (strErrorMsg != "")
  167. {
  168. //写入日志
  169. AppLog.ServiceInfo(strErrorMsg);
  170. }
  171. else
  172. {
  173. if (fileWatcherItem != null) fileWatcherItem.SyncIfChanged = false;
  174. }
  175. }
  176. else
  177. {
  178. AppLog.ServiceInfo("SyncSerivce:未能成功读取日期字段,可能不存在或存在多个日期字段,本次同步失败。");
  179. }
  180. }
  181. private void RunUpLoad(SyncInstrumentItemInfo syncInstrumentItem, DataTable dtReadySource, ref string strMsg)
  182. {
  183. //根据映射字段获取准备上传的所有数据
  184. if (dtReadySource == null || dtReadySource.Rows.Count <= 0) return;
  185. //构建准备插入的数据
  186. DataTable dtTarget = CnasDataOperationFact.CnasDataOperation().GetCNASTablesStruct(syncInstrumentItem.LstSyncPramas[0].TargetTable, syncInstrumentItem.SyncTargetDBInfo);
  187. AppLog.ServiceInfo("读取目标数据的数据结构");
  188. if (dtTarget.Columns.Count <= 0)
  189. {
  190. strMsg = "未能成功读取CNAS数据库列,请检查数据库配置。";
  191. return;
  192. }
  193. CnasInsertOperation insertOperation = new CnasInsertOperation()
  194. {
  195. syncInstrumentItem = syncInstrumentItem
  196. };
  197. AppLog.ServiceInfo("遍历所有来源数据,构造准备插入的数据");
  198. strMsg = insertOperation.CreateInputData(dtReadySource, ref dtTarget);
  199. if (strMsg != "") return;
  200. if (dtTarget.Rows.Count <= 0)
  201. {
  202. strMsg = "创建准备插入的数据行为空。";
  203. return;
  204. }
  205. AppLog.ServiceInfo("检查准备插入的数据是否合法");
  206. insertOperation.CheckInsertDataFormat(dtTarget, ref strMsg);
  207. if (strMsg != "") return;
  208. //逐行执行插入
  209. List<DataRow> lstError = new List<DataRow>();
  210. int ErrorCount = 0;
  211. int SuccessCount = 0;
  212. int OtherCount = 0;
  213. AppLog.ServiceInfo($"逐行插入目标数据,最终准备插入(更新)数据行{dtTarget.Rows.Count}");
  214. int cols = dtTarget.Columns.Count;
  215. foreach (DataRow dr in dtTarget.Rows)
  216. {
  217. if (cols >= 11 && dr[11].ToString().Length > 1)
  218. {
  219. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[11]}");
  220. dr[11] = kxjsf(dr[11].ToString());
  221. }
  222. if (cols >= 12 && dr[12].ToString().Length > 1)
  223. {
  224. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[12]}");
  225. }
  226. if (cols >= 13 && dr[13].ToString().Length > 1)
  227. {
  228. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[13]}");
  229. }
  230. if (cols >= 14 && dr[14].ToString().Length > 1)
  231. {
  232. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[14]}");
  233. }
  234. if (cols >= 15 && dr[15].ToString().Length > 1)
  235. {
  236. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[15]}");
  237. }
  238. if (cols >= 16 && dr[16].ToString().Length > 1)
  239. {
  240. AppLog.Error($"逐行插入目标数据,最终准备插入(更新)数据行{dr[16]}");
  241. }
  242. dr.AcceptChanges();
  243. int iReturn = CnasDataOperationFact.CnasDataOperation().InsertDataToCNASTable(GlobalCommonOperation.ConvertDataRowToTable(dr), syncInstrumentItem.SyncTargetDBInfo, syncInstrumentItem.LstSyncPramas, syncInstrumentItem.CnasInstrumentColumn, syncInstrumentItem.lstFixedValue);
  244. if (iReturn <= 0) //此时出现问题
  245. {
  246. if (iReturn == -1)
  247. {
  248. AppLog.ServiceInfo("数据库连接中断,终止本次上传。");
  249. break; //此时数据库连接中断,直接跳出循环,结束本次数据同步传输
  250. }
  251. else if (iReturn == -2) //等于-2表示插入准备更新时发现数据一致,不再执行
  252. {
  253. OtherCount++;
  254. }
  255. else
  256. {
  257. ErrorCount++;
  258. //lstError.Add(GlobalCommonOperation.ConvertDataRowToTable(dr).Rows[0]);
  259. }
  260. }
  261. else
  262. {
  263. SuccessCount++;
  264. AppLog.Info("成功插入(更新)1条数据。");
  265. }
  266. }
  267. AppLog.ServiceInfo($"上传操作完成!其中成功{SuccessCount}条,失败{ErrorCount}条,其他{OtherCount}条。............................................................................................................");
  268. }
  269. private string kxjsf(string sss)
  270. {
  271. double sd = Convert.ToDouble(sss);
  272. //double sd = 123.123456;
  273. string temps2 = "0";
  274. string temps3 = "0";
  275. string temps4 = "0";
  276. int tempi2 = 0;
  277. int tempi3 = 0;
  278. int tempi4 = 0;
  279. if (sss.Contains('.'))
  280. {
  281. string[] s1 = sss.Split('.');
  282. if (s1[1].Length > 2)
  283. {
  284. if (s1[1].Length > 2)
  285. {
  286. temps2 = s1[1].Substring(1, 1);
  287. temps3 = s1[1].Substring(2, 1);
  288. }
  289. tempi2 = int.Parse(temps2);
  290. tempi3 = int.Parse(temps3);
  291. if (s1[1].Length > 3)
  292. {
  293. temps4 = s1[1].Substring(3, 1);
  294. }
  295. tempi4 = int.Parse(temps4);
  296. if (tempi3 > 5 || tempi3 < 5)
  297. {
  298. return sd.ToString("0.00");
  299. }
  300. else
  301. {
  302. if (tempi4 != 0)
  303. {
  304. return sd.ToString("0.00");
  305. }
  306. else
  307. {
  308. if (tempi2 == 0 || tempi2 == 2 || tempi2 == 4 || tempi2 == 6 || tempi2 == 8)
  309. {
  310. return sss.Substring(0, 5);
  311. }
  312. else
  313. {
  314. return sd.ToString("0.00");
  315. }
  316. }
  317. }
  318. }
  319. }
  320. return sss;
  321. }
  322. private ServiceConfig ReadServiceConfigData()
  323. {
  324. ServiceConfig config = new ServiceConfig();
  325. try
  326. {
  327. //读取本地文件中存储的配置信息
  328. XmlSerializer serializer = new XmlSerializer(config.GetType());
  329. FileStream stream = new FileStream(FileHelper.getBasePath() + "/DataConfig/SyncServiceData.xml", FileMode.Open);
  330. config = (ServiceConfig)serializer.Deserialize(stream);
  331. stream.Close();
  332. }
  333. catch (Exception ex)
  334. {
  335. AppLog.ServiceInfo(ex.Message);
  336. }
  337. return config;
  338. }
  339. /// <summary>
  340. ///
  341. /// </summary>
  342. private Dictionary<string, string> ReadSyncTime()
  343. {
  344. Dictionary<string, string> times = null;
  345. if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache", $"SyncTime.bin")))
  346. {
  347. try
  348. {
  349. using (StreamReader reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Cache", $"SyncTime.bin"), Encoding.UTF8))
  350. {
  351. try
  352. {
  353. string json = reader.ReadToEnd();
  354. times = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
  355. }
  356. catch
  357. {
  358. }
  359. finally
  360. {
  361. reader.Close();
  362. reader.Dispose();
  363. }
  364. }
  365. }
  366. catch (Exception exception)
  367. {
  368. Debug.WriteLine(exception.Message);
  369. }
  370. }
  371. return times;
  372. }
  373. }
  374. }