HeadlessRunner.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. namespace DRG.DRGInterfaceClient
  5. {
  6. /// <summary>--sync 无头模式:供 Windows 任务计划程序调用,完成一次同步后退出。</summary>
  7. internal static class HeadlessRunner
  8. {
  9. public static async Task<int> RunOnceAsync()
  10. {
  11. try
  12. {
  13. var codes = Config.Current.ScheduledHospCodes;
  14. if (codes == null || codes.Count == 0)
  15. {
  16. Logger.Error("ScheduledHospCodes 为空,无法执行 --sync(请在 GUI 勾选机构并「设为定时机构」)");
  17. return 1;
  18. }
  19. if (string.IsNullOrWhiteSpace(Config.Current.Endpoint))
  20. {
  21. Logger.Error("接口地址(Endpoint)为空,无法执行 --sync");
  22. return 1;
  23. }
  24. var hospResp = await DrgApiClient.QueryHospitalInfoAsync("", "",
  25. SessionBuilder.BuildDefault(Config.Current.SessionDefaults));
  26. if (!DrgApiClient.IsOk(hospResp))
  27. {
  28. Logger.Error("加载机构失败: " + DrgApiClient.GetError(hospResp));
  29. return 1;
  30. }
  31. var all = new List<HospitalInfoItem>();
  32. var arr = DrgApiClient.GetResultArray(hospResp);
  33. if (arr != null)
  34. {
  35. foreach (var o in arr)
  36. {
  37. if (o is Dictionary<string, object> d)
  38. all.Add(DrgApiClient.ParseHospital(d));
  39. }
  40. }
  41. int ok = 0, fail = 0;
  42. foreach (var schedCode in codes)
  43. {
  44. var hosp = all.Find(h => string.Equals(h.code, schedCode, StringComparison.OrdinalIgnoreCase));
  45. if (hosp == null)
  46. {
  47. Logger.Error("按 code(医保编码) 匹配不到机构: " + schedCode);
  48. fail++;
  49. continue;
  50. }
  51. var session = SessionBuilder.Build(hosp, Config.Current.SessionDefaults);
  52. var cfgResp = await DrgApiClient.GetSyncConfigAsync(hosp.hospCode, session);
  53. if (!DrgApiClient.IsOk(cfgResp))
  54. {
  55. Logger.Error("机构 " + hosp.descripts + " 配置加载失败: " + DrgApiClient.GetError(cfgResp));
  56. fail++;
  57. continue;
  58. }
  59. var cfg = DrgApiClient.ParseSyncConfig(DrgApiClient.GetResult(cfgResp));
  60. var (st, ed) = DrgApiClient.ComputeDateRange(
  61. cfg.syncType, cfg.lookbackDays, Config.Current.FullSyncStartDays);
  62. // 跨度超过一天时按天拆分,每天一次 02010067,避免大区间请求超时
  63. var batches = DrgApiClient.SplitByDay(st, ed);
  64. Logger.Info(string.Format("机构 {0} 区间[{1},{2}] 拆分为 {3} 批(按天执行 02010067)",
  65. hosp.descripts, st, ed, batches.Count));
  66. int dayOk = 0, dayFail = 0;
  67. foreach (var b in batches)
  68. {
  69. var syncResp = await DrgApiClient.GetInpatientDataAsync(
  70. hosp.hospCode, b.Item1, b.Item2, cfg.synFlag ?? "Y", session);
  71. if (DrgApiClient.IsOk(syncResp))
  72. {
  73. dayOk++;
  74. Logger.Info(string.Format("机构 {0} 日期 {1} 同步成功", hosp.descripts, b.Item1));
  75. }
  76. else
  77. {
  78. dayFail++;
  79. Logger.Error(string.Format("机构 {0} 日期 {1} 同步失败: {2}",
  80. hosp.descripts, b.Item1, DrgApiClient.GetError(syncResp)));
  81. }
  82. }
  83. if (dayFail == 0)
  84. {
  85. Logger.Info(string.Format("机构 {0} 同步成功({1} 天全部成功)", hosp.descripts, dayOk));
  86. ok++;
  87. }
  88. else
  89. {
  90. Logger.Error(string.Format("机构 {0} 同步完成但存在失败:成功 {1} 天,失败 {2} 天",
  91. hosp.descripts, dayOk, dayFail));
  92. fail++;
  93. }
  94. }
  95. Logger.Info(string.Format("sync 完成:成功 {0} 家,失败 {1} 家(共 {2} 家)", ok, fail, codes.Count));
  96. return fail > 0 ? 1 : 0;
  97. }
  98. catch (Exception ex)
  99. {
  100. Logger.Error("--sync 执行异常", ex);
  101. return 1;
  102. }
  103. }
  104. }
  105. }