DrgApiClient.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Net.Http;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Web.Script.Serialization;
  8. namespace DRG.DRGInterfaceClient
  9. {
  10. /// <summary>DRG 平台接口 HTTP 客户端(复用 HISAutoSyncService/ConfigApiClient 模式)。</summary>
  11. internal static class DrgApiClient
  12. {
  13. private static readonly HttpClient _http = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
  14. private static readonly JavaScriptSerializer _json = new JavaScriptSerializer();
  15. // ===== 通用调用(所有调用均带 session) =====
  16. public static async Task<Dictionary<string, object>> CallAsync(
  17. string code, object paramObj, Dictionary<string, object> session)
  18. {
  19. AppConfig cfg = Config.Current;
  20. var payload = new Dictionary<string, object>
  21. {
  22. { "code", code },
  23. { "params", new[] { paramObj } },
  24. { "session", new[] { session ?? new Dictionary<string, object>() } }
  25. };
  26. string json = _json.Serialize(payload);
  27. var req = new HttpRequestMessage(HttpMethod.Post, cfg.Endpoint);
  28. req.Content = new StringContent(json, Encoding.UTF8, "application/json");
  29. req.Headers.TryAddWithoutValidation("Authorization", "Basic " + cfg.AuthToken);
  30. var sw = Stopwatch.StartNew();
  31. try
  32. {
  33. var resp = await _http.SendAsync(req).ConfigureAwait(false);
  34. var text = await resp.Content.ReadAsStringAsync().ConfigureAwait(false);
  35. sw.Stop();
  36. Logger.Info(string.Format("[{0}] 请求: {1}", code, json));
  37. Logger.Info(string.Format("[{0}] HTTP {1} 耗时{2}ms 响应: {3}",
  38. code, (int)resp.StatusCode, sw.ElapsedMilliseconds, text));
  39. try { return _json.Deserialize<Dictionary<string, object>>(text); }
  40. catch (Exception ex)
  41. {
  42. Logger.Error("解析响应失败:" + code, ex);
  43. return ErrorDict(ex);
  44. }
  45. }
  46. catch (Exception ex)
  47. {
  48. sw.Stop();
  49. Logger.Error(string.Format("调用异常 [{0}] 耗时{1}ms", code, sw.ElapsedMilliseconds), ex);
  50. return ErrorDict(ex);
  51. }
  52. }
  53. // ===== 业务接口 =====
  54. public static Task<Dictionary<string, object>> QueryHospitalInfoAsync(
  55. string active, string descripts, Dictionary<string, object> session)
  56. {
  57. return CallAsync("01010064", new { active = active ?? "", descripts = descripts ?? "" }, session);
  58. }
  59. public static Task<Dictionary<string, object>> GetSyncConfigAsync(
  60. string hospCode, Dictionary<string, object> session)
  61. {
  62. return CallAsync("02010079", new { hospCode }, session);
  63. }
  64. public static Task<Dictionary<string, object>> GetInpatientDataAsync(
  65. string hospCode, string stDate, string endDate, string synFlag, Dictionary<string, object> session)
  66. {
  67. return CallAsync("02010067",
  68. new { admID = "", hospID = hospCode, stDate, endDate, SynFlag = synFlag }, session);
  69. }
  70. // ===== 响应解析辅助 =====
  71. public static bool IsOk(Dictionary<string, object> resp)
  72. {
  73. if (resp == null) return false;
  74. return resp.TryGetValue("errorCode", out object ec)
  75. && ec != null && ec.ToString() == "0";
  76. }
  77. public static string GetError(Dictionary<string, object> resp)
  78. {
  79. if (resp == null) return "响应为空";
  80. var msg = resp.TryGetValue("errorMessage", out object m) ? (m ?? "").ToString() : "";
  81. var ec = resp.TryGetValue("errorCode", out object e) ? (e ?? "").ToString() : "";
  82. return string.IsNullOrEmpty(msg) ? ("errorCode=" + ec) : msg;
  83. }
  84. public static Dictionary<string, object> GetResult(Dictionary<string, object> resp)
  85. {
  86. if (resp == null) return null;
  87. if (resp.TryGetValue("result", out object r) && r is Dictionary<string, object> dict) return dict;
  88. return null;
  89. }
  90. public static object[] GetResultArray(Dictionary<string, object> resp)
  91. {
  92. if (resp == null) return null;
  93. if (resp.TryGetValue("result", out object r))
  94. {
  95. if (r is object[] arr) return arr;
  96. if (r is System.Collections.ArrayList list)
  97. return (object[])list.ToArray(typeof(object));
  98. }
  99. return null;
  100. }
  101. // ===== 模型解析 =====
  102. public static HospitalInfoItem ParseHospital(Dictionary<string, object> d)
  103. {
  104. if (d == null) return new HospitalInfoItem();
  105. return new HospitalInfoItem
  106. {
  107. id = GetStr(d, "id"),
  108. hospCode = GetStr(d, "hospCode"),
  109. code = GetStr(d, "code"),
  110. descripts = GetStr(d, "descripts"),
  111. MedinsLv = GetStr(d, "MedinsLv")
  112. };
  113. }
  114. public static SyncConfig ParseSyncConfig(Dictionary<string, object> r)
  115. {
  116. if (r == null) return null;
  117. return new SyncConfig
  118. {
  119. syncType = GetStr(r, "syncType"),
  120. frequency = GetStr(r, "frequency"),
  121. scheduledTime = GetStr(r, "scheduledTime"),
  122. lookbackDays = GetInt(r, "lookbackDays", 3),
  123. enabled = GetBool(r, "enabled", false),
  124. synFlag = GetStr(r, "synFlag", "Y"),
  125. warningFlag = GetStr(r, "warningFlag", "Y"),
  126. status = GetStr(r, "status"),
  127. errorMessage = GetStr(r, "errorMessage")
  128. };
  129. }
  130. /// <summary>根据 syncType 与 lookbackDays 计算 02010067 的日期区间(yyyy-MM-dd)。</summary>
  131. public static (string stDate, string endDate) ComputeDateRange(
  132. string syncType, int lookbackDays, int fullSyncStartDays)
  133. {
  134. string today = DateTime.Now.ToString("yyyy-MM-dd");
  135. if (syncType == "full")
  136. {
  137. string st = fullSyncStartDays > 0
  138. ? DateTime.Now.AddDays(-fullSyncStartDays).ToString("yyyy-MM-dd")
  139. : "";
  140. return (st, today);
  141. }
  142. int lb = lookbackDays > 0 ? lookbackDays : 3;
  143. return (DateTime.Now.AddDays(-lb).ToString("yyyy-MM-dd"), today);
  144. }
  145. // ===== 内部工具 =====
  146. public static string GetStr(Dictionary<string, object> d, string k, string def = "")
  147. {
  148. if (d.TryGetValue(k, out object v) && v != null) return v.ToString();
  149. return def;
  150. }
  151. public static int GetInt(Dictionary<string, object> d, string k, int def)
  152. {
  153. if (d.TryGetValue(k, out object v) && v != null)
  154. {
  155. if (v is int i) return i;
  156. if (v is long l) return (int)l;
  157. if (int.TryParse(v.ToString(), out int r)) return r;
  158. }
  159. return def;
  160. }
  161. public static bool GetBool(Dictionary<string, object> d, string k, bool def)
  162. {
  163. if (d.TryGetValue(k, out object v) && v != null)
  164. {
  165. var s = v.ToString();
  166. if (s == "1" || string.Equals(s, "true", StringComparison.OrdinalIgnoreCase)
  167. || string.Equals(s, "Y", StringComparison.OrdinalIgnoreCase)) return true;
  168. if (s == "0" || string.Equals(s, "false", StringComparison.OrdinalIgnoreCase)
  169. || string.Equals(s, "N", StringComparison.OrdinalIgnoreCase)) return false;
  170. }
  171. return def;
  172. }
  173. private static Dictionary<string, object> ErrorDict(Exception ex)
  174. {
  175. return new Dictionary<string, object>
  176. {
  177. { "errorCode", "-1" },
  178. { "errorMessage", "异常: " + ex.Message }
  179. };
  180. }
  181. }
  182. }