CNAS取数仪器端升级
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

373 lignes
15KB

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