CNAS取数仪器端升级
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

SyncServiceOperation.cs 15KB

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