InvokeHelper.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. /******************************************************************************
  2. * 文件名称: InvokeHelper.cs
  3. * 文件说明: 调用助手,调用方法的封装
  4. * 当前版本: V1.0
  5. * 创建日期: 2022-04-12
  6. *
  7. * 2020-04-12: 增加 businessDLLInvoke 方法
  8. * 2020-04-12: 增加 writeLog 方法
  9. * 2020-04-14: 增加 businessDLLInvoke(重载) 方法
  10. * 2020-04-14: 增加 irisServiceInvoke 方法
  11. ******************************************************************************/
  12. using Newtonsoft.Json.Linq;
  13. using System;
  14. using System.Collections.Generic;
  15. using System.IO;
  16. using System.Linq;
  17. using System.Net;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. using System.Windows.Forms;
  21. using PTMedicalInsurance.Helper;
  22. using Newtonsoft.Json;
  23. using PTMedicalInsurance.Common;
  24. using PTMedicalInsurance.Variables;
  25. using System.Runtime.InteropServices;
  26. using PTMedicalInsurance.Forms;
  27. namespace PTMedicalInsurance.Helper
  28. {
  29. public class InvokeHelper
  30. {
  31. private string serviceURL;
  32. private string authorization;
  33. public InvokeHelper()
  34. {
  35. LoadCenterURL(false);
  36. }
  37. private void LoadCenterURL(bool reloadFromCfgFile)
  38. {
  39. IniFile ini = new IniFile(Global.curEvt.path + @"\CenterServiceURL.ini");
  40. // 默认采用的是后台配置的地址
  41. if (reloadFromCfgFile)
  42. {
  43. Global.inf.centerURL = ini.ReadValue("CENTER", "url");
  44. Global.inf.uploadURL = ini.ReadValue("CENTER", "upload");
  45. Global.inf.downURL = ini.ReadValue("CENTER", "download");
  46. }
  47. Global.inf.ecURL = ini.ReadValue("CENTER", "ecToken");
  48. Global.inf.mobilePayURL = ini.ReadValue("CENTER", "mobilePay");
  49. Global.inf.ecPrescURL = ini.ReadValue("CENTER", "prescription");
  50. // 移动支付
  51. if (string.IsNullOrEmpty(Global.inf.mobilePayURL))
  52. {
  53. Global.inf.mobilePayURL = "http://10.77.224.18:9001/CSB/hsa-fsi-no";
  54. }
  55. // 电子处方
  56. if (string.IsNullOrEmpty(Global.inf.ecPrescURL))
  57. {
  58. Global.inf.ecPrescURL = "http://10.77.245.22:9001/epc/api";
  59. }
  60. }
  61. /// <summary>
  62. /// API密钥
  63. /// </summary>
  64. private void LoadAPIKey(string prefix)
  65. {
  66. //获取AK,SK(可配置)
  67. IniFile urlIni = new IniFile(Global.curEvt.path + @"\EncrypInfo.ini");
  68. string ak = urlIni.ReadValue(prefix, "AK");
  69. string sk = urlIni.ReadValue(prefix, "SK");
  70. if (!string.IsNullOrEmpty(ak) && !string.IsNullOrEmpty(sk))
  71. {
  72. Global.inf.AK = ak;
  73. Global.inf.SK = sk;
  74. }
  75. }
  76. /// <summary>
  77. /// 核心接口密钥
  78. /// </summary>
  79. private void LoadCoreAPIKey()
  80. {
  81. LoadAPIKey("KEY");
  82. }
  83. /// <summary>
  84. /// 移动支付密钥
  85. /// </summary>
  86. private void LoadMobileAPIKey()
  87. {
  88. LoadAPIKey("MOBILE");
  89. }
  90. #region 内部服务调用
  91. /// <summary>
  92. /// iris服务调用的封装
  93. /// </summary>
  94. /// <param name="data"></param>
  95. /// <returns></returns>
  96. public JObject invokeIrisService(string data, string serviceDesc)
  97. {
  98. string rtn = "", url = "";
  99. JObject joRtn = new JObject();
  100. try
  101. {
  102. //先根据用户请求的uri构造请求地址
  103. url = serviceURL;
  104. ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
  105. ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
  106. //创建Web访问对象
  107. HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
  108. //把用户传过来的数据转成“UTF-8”的字节流
  109. byte[] buf = System.Text.Encoding.GetEncoding("UTF-8").GetBytes(data);
  110. //添加头部信息
  111. myRequest.Method = "POST";
  112. myRequest.ContentLength = buf.Length;
  113. myRequest.ContentType = "application/json";
  114. myRequest.Headers.Add("Authorization", authorization);
  115. myRequest.MaximumAutomaticRedirections = 1;
  116. myRequest.AllowAutoRedirect = true;
  117. //发送请求
  118. Stream stream = myRequest.GetRequestStream();
  119. stream.Write(buf, 0, buf.Length);
  120. stream.Close();
  121. //获取接口返回值
  122. //通过Web访问对象获取响应内容
  123. HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
  124. rtn = getResponseData(myResponse);
  125. joRtn = JObject.Parse(rtn);
  126. return joRtn;
  127. }
  128. catch (Exception ex)
  129. {
  130. joRtn = JsonHelper.setExceptionJson(-1, serviceDesc, ex.Message);
  131. rtn = JsonConvert.SerializeObject(joRtn);
  132. return joRtn;
  133. }
  134. }
  135. /// <summary>
  136. /// HIS服务调用的封装
  137. /// </summary>
  138. /// <param name="data"></param>
  139. /// <returns></returns>
  140. ///
  141. public JObject invokeHISService(string data, string serviceDesc)
  142. {
  143. JObject joRtn = new JObject();
  144. try
  145. {
  146. //先根据用户请求的uri构造请求地址
  147. serviceURL = string.Format("{0}/{1}", Global.hisConfig.ip, Global.hisConfig.url);
  148. authorization = Global.hisConfig.authorization;
  149. joRtn = invokeIrisService(data, serviceDesc);
  150. return joRtn;
  151. }
  152. catch (Exception ex)
  153. {
  154. joRtn = JsonHelper.setExceptionJson(-1, serviceDesc, ex.Message);
  155. return joRtn;
  156. }
  157. finally
  158. {
  159. Global.writeLog_Iris(serviceDesc + "(" + serviceURL + ")" + "Authorization:" + (authorization), JsonHelper.Compress(data), JsonHelper.Compress(joRtn));
  160. }
  161. }
  162. /// <summary>
  163. /// 医保平台服务调用的封装
  164. /// </summary>
  165. /// <param name="data"></param>
  166. /// <returns></returns>
  167. public JObject invokeInsuService(string data, string serviceDesc)
  168. {
  169. string rtn = "";
  170. JObject joRtn = new JObject();
  171. try
  172. {
  173. //先根据用户请求的uri构造请求地址
  174. serviceURL = string.Format("{0}/{1}", Global.insuConfig.ip, Global.insuConfig.url);
  175. authorization = Global.insuConfig.authorization;
  176. joRtn = invokeIrisService(data, serviceDesc);
  177. rtn = JsonConvert.SerializeObject(joRtn);
  178. //if (serviceDesc == "插入签到信息")
  179. //{
  180. // MessageBox.Show("插入签到信息入参:" + data +"|返回值:"+ rtn.ToString()+"|"+ Global.insuConfig.url);
  181. //}
  182. return joRtn;
  183. }
  184. catch (Exception ex)
  185. {
  186. joRtn = JsonHelper.setExceptionJson(-1, serviceDesc, ex.Message);
  187. rtn = JsonConvert.SerializeObject(joRtn);
  188. return joRtn;
  189. }
  190. finally
  191. {
  192. Global.writeLog_Iris(serviceDesc + "(" + serviceURL + ")" + "Authorization:" + (authorization), JsonHelper.Compress(data), rtn);
  193. }
  194. }
  195. private string getResponseData(HttpWebResponse response)
  196. {
  197. string data = "";
  198. if (response != null)
  199. {
  200. Stream s = response.GetResponseStream();
  201. StreamReader sRead = new StreamReader(s);
  202. data = sRead.ReadToEnd();
  203. sRead.Close();
  204. response.Close();
  205. }
  206. return data;
  207. }
  208. #endregion
  209. #region 医保中心调用
  210. /// <summary>
  211. /// 仅辅助交易、自定义交易使用
  212. /// </summary>
  213. /// <param name="funNo"></param>
  214. /// <param name="joInput"></param>
  215. /// <returns></returns>
  216. public JObject invokeCenterAgentService(string funNo, JObject joInput)
  217. {
  218. Global.curEvt.URL = Global.inf.centerURL + funNo;
  219. string data = JsonHelper.setCenterInpar(funNo, joInput);
  220. return invokeCenterService(data);
  221. }
  222. private JObject invokeCenterService(string data, ModeEnum mode = ModeEnum.REST)
  223. {
  224. JObject joRtn = new JObject();
  225. try
  226. {
  227. IInvokeCenter center = new InvokeCenterFactory().create(mode);
  228. string outputData = "";
  229. string errMsg = "";
  230. int iInt = center.Init(ref errMsg);
  231. if (iInt == 0)
  232. {
  233. LoadCoreAPIKey();
  234. iInt = center.Business(data, ref outputData, ref errMsg);
  235. if (iInt == 0 && !string.IsNullOrEmpty(outputData))
  236. {
  237. try
  238. {
  239. joRtn = JObject.Parse(outputData);
  240. }
  241. catch (Exception ex)
  242. {
  243. joRtn.Add("infcode", iInt);
  244. joRtn.Add("err_msg", "返回参数异常:" + outputData);
  245. }
  246. }
  247. else
  248. {
  249. joRtn.Add("infcode", iInt);
  250. joRtn.Add("err_msg", outputData);
  251. return joRtn;
  252. }
  253. return joRtn;
  254. }
  255. else
  256. {
  257. joRtn.Add("infcode", -1);
  258. joRtn.Add("err_msg", "医保动态库初始化失败invokeInitByDLL:" + errMsg);
  259. return joRtn;
  260. }
  261. }
  262. finally
  263. {
  264. Global.writeLog("调用中心:", JsonHelper.Compress(data), joRtn.ToString());
  265. // 保存到服务器
  266. this.saveCenterLog(JsonHelper.Compress(data),joRtn.ToString(), JsonHelper.Compress(data), joRtn.ToString());
  267. }
  268. }
  269. private void prepareCallURI(TradeEnum trade)
  270. {
  271. string funNo = trade.GetCode() ;
  272. Global.curEvt.funNo = funNo;
  273. if (Global.curEvt.testMode)
  274. {
  275. // 医保测试环境
  276. LoadCenterURL(true);
  277. }
  278. string prefix = Global.inf.centerURL;
  279. switch (trade)
  280. {
  281. case TradeEnum.FileUpload:
  282. prefix = Global.inf.uploadURL??Global.inf.centerURL;
  283. break;
  284. case TradeEnum.FileDownload:
  285. prefix = Global.inf.downURL;
  286. break;
  287. default:
  288. prefix = Global.inf.centerURL;
  289. break;
  290. }
  291. // 根据情况确实是否需要加funNo
  292. Global.curEvt.URL = prefix + Global.curEvt.funNo;
  293. }
  294. /// <summary>
  295. /// 通过枚举转换要调用的接口
  296. /// </summary>
  297. /// <param name="trade"></param>
  298. /// <param name="data"></param>
  299. /// <returns></returns>
  300. public JObject invokeCenterService(TradeEnum trade, JObject joInput)
  301. {
  302. string funNo = trade.GetCode();
  303. // 入参统一转换
  304. JObject request = Utils.ConvertRequest<JObject>(trade,joInput);
  305. string data = JsonHelper.toJsonString(request);
  306. // 统一封装请求头
  307. if (trade.GetMode() == ModeEnum.REST)
  308. {
  309. data = JsonHelper.setCenterInpar(funNo, request);
  310. }
  311. JObject joRtn = new JObject();
  312. // 调试模式
  313. if (Global.curEvt.enabledDebug)
  314. {
  315. CenterResult center = new CenterResult();
  316. center.setTradeNo(trade.GetCode(), data);
  317. if (center.ShowDialog() == DialogResult.OK)
  318. {
  319. // 接口实际返回数据
  320. string outPar = center.returnData;
  321. joRtn = JObject.Parse(outPar);
  322. }
  323. }
  324. else
  325. {
  326. prepareCallURI(trade);
  327. joRtn = invokeCenterService(data, trade.GetMode());
  328. }
  329. // 返回结果统一转换
  330. joRtn = Utils.ConvertResponse<JObject>(trade,joRtn);
  331. return joRtn;
  332. }
  333. /// <summary>
  334. /// 医保目录txt文件下载
  335. /// </summary>
  336. /// <param name="data"></param>
  337. /// <returns></returns>
  338. public JObject DownloadCenterFile(string data, ModeEnum mode = ModeEnum.REST)
  339. {
  340. //download file
  341. IInvokeCenter center = new InvokeCenterFactory().create(mode);
  342. string outputMsg = "";
  343. JObject joRtn = new JObject();
  344. int rtnCode = center.DownloadFile(data, ref outputMsg);
  345. if(rtnCode==0)
  346. {
  347. joRtn = JObject.Parse(outputMsg);
  348. }
  349. else
  350. {
  351. joRtn.Add("infcode", -1);
  352. joRtn.Add("err_msg", "下载文件失败DownloadFile:" + outputMsg);
  353. }
  354. return joRtn;
  355. }
  356. #endregion
  357. #region 移动
  358. /// <summary>
  359. /// 移动
  360. /// </summary>
  361. /// <param name="funNO"></param>
  362. /// <param name="data"></param>
  363. /// <returns></returns>
  364. public JObject invokeMPService(string funNO, string data)
  365. {
  366. return invokeMPService(funNO, JObject.Parse(data));
  367. }
  368. public JObject invokeMPService(string funNO, JObject joInput)
  369. {
  370. JObject joRtn = new JObject();
  371. String outPar = "";
  372. try
  373. {
  374. string url = "";
  375. //switch (funNO)
  376. //{
  377. // case "6201":
  378. // url = "/org/local/api/hos/uldFeeInfo";
  379. // break;
  380. // case "6202":
  381. // url = "/org/local/api/hos/pay_order";
  382. // break;
  383. // case "6203":
  384. // url = "/org/local/api/hos/refund_Order";
  385. // break;
  386. // case "6301":
  387. // url = "/org/local/api/hos/query_order_info";
  388. // break;
  389. // case "6401":
  390. // url = "/org/local/api/hos/revoke_order";
  391. // break;
  392. // default:
  393. // break;
  394. //}
  395. EncryptHelper encrypt = new EncryptHelper();
  396. string data = JsonHelper.setMPCenterInpar(funNO, joInput);
  397. // 移动支付地址
  398. Global.curEvt.URL = Global.inf.mobilePayURL + funNO;
  399. string outputData = "", errMsg = "";
  400. // 动态调试模式
  401. if (Global.curEvt.enabledDebug)
  402. {
  403. CenterResult center = new CenterResult();
  404. center.setTradeNo(funNO,data);
  405. if (center.ShowDialog() == DialogResult.OK)
  406. {
  407. outPar = center.returnData;
  408. return JObject.Parse(outPar);
  409. }
  410. }
  411. try
  412. {
  413. InvokeRestCenter mobileCenter = new InvokeRestCenter();
  414. LoadMobileAPIKey();
  415. int iInt = mobileCenter.Business(data, ref outputData, ref errMsg);
  416. joRtn = JObject.Parse(outputData);
  417. Global.writeLog(funNO + "【密文出参】:\r\n" + joRtn.ToString());
  418. string encData = JsonHelper.getDestValue(joRtn, "encData");
  419. string signData = JsonHelper.getDestValue(joRtn, "signData");
  420. if (!string.IsNullOrEmpty(encData) && !string.IsNullOrEmpty(signData))
  421. {
  422. joRtn.Remove("encData");
  423. joRtn.Remove("signData");
  424. joRtn.Remove("data");
  425. //解密
  426. string decData = encrypt.decrypt(encData);
  427. // 验签
  428. JsonConvert.DefaultSettings = () => new JsonSerializerSettings
  429. {
  430. FloatParseHandling = FloatParseHandling.Decimal
  431. };
  432. joRtn.Add("data", JToken.FromObject(JsonConvert.DeserializeObject(decData)));
  433. bool rtn = encrypt.verify(joRtn, signData);
  434. if (rtn)
  435. {
  436. Global.writeLog(funNO + "【明文出参】:\r\n" + decData);
  437. joRtn = JObject.Parse(decData);
  438. joRtn.Add("success", "True");
  439. }
  440. else
  441. {
  442. Global.writeLog("验签失败,请核查!");
  443. }
  444. }
  445. return joRtn;
  446. }
  447. finally
  448. {
  449. string plainData = data;
  450. data = JsonHelper.setCenterInpar(funNO,JObject.Parse(data));
  451. this.saveCenterLog(JsonHelper.Compress(data), joRtn.ToString(), JsonHelper.Compress(plainData), joRtn.ToString());
  452. }
  453. }
  454. catch (Exception ex)
  455. {
  456. if (joRtn["infcode"] == null)
  457. { joRtn.Add("infcode", -1); }
  458. if (joRtn["err_msg"] == null)
  459. { joRtn.Add("err_msg", "invokeCenterService(3):" + ex.Message); }
  460. outPar = JsonHelper.Compress(joRtn);
  461. return joRtn;
  462. }
  463. finally
  464. {
  465. Global.writeLog(funNO + "(" + Global.curEvt.URL + ")", joInput.ToString(), joRtn.ToString());
  466. this.saveCenterLog(joInput.ToString(), joRtn.ToString(), joInput.ToString(), joRtn.ToString());
  467. }
  468. }
  469. /// <summary>
  470. /// 保存中心交易日志到数据库
  471. /// </summary>
  472. /// <param name="inParam"></param>
  473. /// <param name="outParam"></param>
  474. /// <param name="inParamPlain"></param>
  475. /// <param name="outParamPlain"></param>
  476. private void saveCenterLog(string inParam, string outParam, string inParamPlain, string outParamPlain)
  477. {
  478. dynamic joIris = new JObject();
  479. string sRtn = "";
  480. try
  481. {
  482. //解析postContent,插入医保交易日志表
  483. JObject joInParam = new JObject(JObject.Parse(inParam));
  484. //解包
  485. JObject joIn = Utils.removeWrapper(joInParam);
  486. JObject joOut = new JObject(JObject.Parse(outParam));
  487. JObject joInPlain = new JObject(JObject.Parse(inParamPlain));
  488. JObject joOutPlain = new JObject(JObject.Parse(outParamPlain));
  489. JArray jaParams = new JArray();
  490. JObject joParam = new JObject();
  491. joParam.Add("inParam", JObject.FromObject(joIn));
  492. joParam.Add("outParam", JObject.FromObject(joOut));
  493. joParam.Add("inParamPlain", JObject.FromObject(joInPlain));
  494. joParam.Add("outParamPlain", JObject.FromObject(joOutPlain));
  495. joParam.Add("HospitalDr", Global.inf.hospitalDr);
  496. joParam.Add("InterfaceDr", Global.inf.interfaceDr);
  497. joParam.Add("updateUserID", Global.user.ID);
  498. joParam.Add("psn_no", Global.pat.psn_no);
  499. jaParams.Add(joParam);
  500. joIris.code = "09010021";
  501. joIris.Add("params", jaParams);
  502. //InvokeHelper invoker = new InvokeHelper();
  503. sRtn = invokeInsuService(joIris.ToString(), "保存日志到数据库").ToString();
  504. }
  505. catch (Exception ex)
  506. {
  507. sRtn = JsonHelper.setExceptionJson(-100, "保存日志异常", ex.Message).ToString();
  508. Global.writeLog_Iris("保存日志异常:" + sRtn.ToString());
  509. }
  510. }
  511. #endregion
  512. }
  513. }