HuaShiController.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399
  1. using Newtonsoft.Json.Linq;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Web.Http;
  5. namespace ThCardReader
  6. {
  7. /// <summary>
  8. /// 华视电子读卡器专用API控制器
  9. /// 独立于现有的EntryController,不影响原有医保业务
  10. /// </summary>
  11. public class HuaShiController : ApiController
  12. {
  13. /// <summary>
  14. /// 初始化华视读卡器
  15. /// </summary>
  16. /// <param name="port">端口号:1-16为串口,1001-1016为USB口</param>
  17. /// <returns>初始化结果</returns>
  18. [HttpPost]
  19. [Route("readcard/huashi/init")]
  20. public IHttpActionResult InitHuaShiReader([FromBody] dynamic request)
  21. {
  22. try
  23. {
  24. int port = 1001; // 默认USB端口1
  25. if (request != null && request.port != null)
  26. {
  27. port = (int)request.port;
  28. }
  29. var result = HuaShiIdCardBusiness.Initialize(port);
  30. if ((int)result["code"] == 200)
  31. {
  32. return Ok(result);
  33. }
  34. else
  35. {
  36. return BadRequest(result.ToString());
  37. }
  38. }
  39. catch (Exception ex)
  40. {
  41. var errorResult = new JObject
  42. {
  43. ["code"] = 1001,
  44. ["message"] = $"华视读卡器初始化异常: {ex.Message}",
  45. ["device"] = "华视电子身份证读卡器"
  46. };
  47. return BadRequest(errorResult.ToString());
  48. }
  49. }
  50. /// <summary>
  51. /// 读取身份证信息
  52. /// </summary>
  53. /// <returns>身份证信息</returns>
  54. [HttpPost]
  55. [Route("readcard/huashi/readcard")]
  56. public IHttpActionResult ReadIdCard([FromBody] dynamic request)
  57. {
  58. try
  59. {
  60. string savePath = "";
  61. bool autoClose = false;
  62. if (request != null)
  63. {
  64. if (request.savePath != null)
  65. {
  66. savePath = (string)request.savePath;
  67. }
  68. if (request.autoClose != null)
  69. {
  70. autoClose = (bool)request.autoClose;
  71. }
  72. }
  73. var result = HuaShiIdCardBusiness.ReadIdCard(savePath, autoClose);
  74. if ((int)result["code"] == 200)
  75. {
  76. return Ok(result);
  77. }
  78. else
  79. {
  80. return BadRequest(result.ToString());
  81. }
  82. }
  83. catch (Exception ex)
  84. {
  85. var errorResult = new JObject
  86. {
  87. ["code"] = 1001,
  88. ["message"] = $"华视读卡器读卡异常: {ex.Message}",
  89. ["device"] = "华视电子身份证读卡器"
  90. };
  91. return BadRequest(errorResult.ToString());
  92. }
  93. }
  94. /// <summary>
  95. /// 连续读卡模式
  96. /// </summary>
  97. /// <returns>身份证信息</returns>
  98. [HttpPost]
  99. [Route("readcard/huashi/readcard/continuous")]
  100. public IHttpActionResult ReadIdCardContinuous([FromBody] dynamic request)
  101. {
  102. try
  103. {
  104. string savePath = "";
  105. bool autoClose = false;
  106. if (request != null)
  107. {
  108. if (request.savePath != null)
  109. {
  110. savePath = (string)request.savePath;
  111. }
  112. if (request.autoClose != null)
  113. {
  114. autoClose = (bool)request.autoClose;
  115. }
  116. }
  117. var result = HuaShiIdCardBusiness.ReadIdCardContinuous(savePath, autoClose);
  118. if ((int)result["code"] == 200)
  119. {
  120. return Ok(result);
  121. }
  122. else
  123. {
  124. return BadRequest(result.ToString());
  125. }
  126. }
  127. catch (Exception ex)
  128. {
  129. var errorResult = new JObject
  130. {
  131. ["code"] = 1001,
  132. ["message"] = $"华视连续读卡异常: {ex.Message}",
  133. ["device"] = "华视电子身份证读卡器"
  134. };
  135. return BadRequest(errorResult.ToString());
  136. }
  137. }
  138. /// <summary>
  139. /// 获取设备状态
  140. /// </summary>
  141. /// <returns>设备状态信息</returns>
  142. [HttpGet]
  143. [Route("readcard/huashi/status")]
  144. public IHttpActionResult GetDeviceStatus()
  145. {
  146. try
  147. {
  148. var result = HuaShiIdCardBusiness.GetDeviceStatus();
  149. if ((int)result["code"] == 200)
  150. {
  151. return Ok(result);
  152. }
  153. else
  154. {
  155. return BadRequest(result.ToString());
  156. }
  157. }
  158. catch (Exception ex)
  159. {
  160. var errorResult = new JObject
  161. {
  162. ["code"] = 1001,
  163. ["message"] = $"获取华视设备状态异常: {ex.Message}",
  164. ["device"] = "华视电子身份证读卡器"
  165. };
  166. return BadRequest(errorResult.ToString());
  167. }
  168. }
  169. /// <summary>
  170. /// 关闭华视读卡器连接
  171. /// </summary>
  172. /// <returns>关闭结果</returns>
  173. [HttpPost]
  174. [Route("readcard/huashi/close")]
  175. public IHttpActionResult CloseReader()
  176. {
  177. try
  178. {
  179. var result = HuaShiIdCardBusiness.Close();
  180. return Ok(result);
  181. }
  182. catch (Exception ex)
  183. {
  184. var errorResult = new JObject
  185. {
  186. ["code"] = 1001,
  187. ["message"] = $"关闭华视读卡器异常: {ex.Message}",
  188. ["device"] = "华视电子身份证读卡器"
  189. };
  190. return BadRequest(errorResult.ToString());
  191. }
  192. }
  193. /// <summary>
  194. /// 获取华视API文档
  195. /// </summary>
  196. /// <returns>API文档信息</returns>
  197. [HttpGet]
  198. [Route("readcard/huashi/help")]
  199. public IHttpActionResult GetApiHelp()
  200. {
  201. var help = new JObject
  202. {
  203. ["device"] = "华视电子身份证读卡器",
  204. ["version"] = "V3.3.0.7",
  205. ["manufacturer"] = "深圳华视电子读写设备有限公司",
  206. ["apis"] = new JArray
  207. {
  208. new JObject
  209. {
  210. ["method"] = "POST",
  211. ["url"] = "/readcard/huashi/init",
  212. ["description"] = "初始化华视读卡器",
  213. ["parameters"] = new JObject
  214. {
  215. ["port"] = "端口号:1-16为串口COM1-COM16,1001-1016为USB口1-16"
  216. },
  217. ["example"] = new JObject
  218. {
  219. ["port"] = 1001
  220. }
  221. },
  222. new JObject
  223. {
  224. ["method"] = "POST",
  225. ["url"] = "/readcard/huashi/readcard",
  226. ["description"] = "读取身份证信息",
  227. ["parameters"] = new JObject
  228. {
  229. ["savePath"] = "照片保存路径(可选)",
  230. ["autoClose"] = "读卡后是否自动关闭连接(可选,默认false,URL调用建议true)"
  231. },
  232. ["example"] = new JObject
  233. {
  234. ["savePath"] = "C:/photos",
  235. ["autoClose"] = true
  236. }
  237. },
  238. new JObject
  239. {
  240. ["method"] = "POST",
  241. ["url"] = "/readcard/huashi/readcard/continuous",
  242. ["description"] = "连续读卡模式(不需要重新放置卡片)",
  243. ["parameters"] = new JObject
  244. {
  245. ["savePath"] = "照片保存路径(可选)",
  246. ["autoClose"] = "读卡后是否自动关闭连接(可选,默认false,URL调用建议true)"
  247. }
  248. },
  249. new JObject
  250. {
  251. ["method"] = "GET",
  252. ["url"] = "/readcard/huashi/status",
  253. ["description"] = "获取设备状态"
  254. },
  255. new JObject
  256. {
  257. ["method"] = "POST",
  258. ["url"] = "/readcard/huashi/close",
  259. ["description"] = "关闭读卡器连接"
  260. }
  261. },
  262. ["supportedCards"] = new JArray
  263. {
  264. "居民身份证",
  265. "外国人永久居留证",
  266. "港澳台居民居住证",
  267. "新版外国人居留证"
  268. },
  269. ["returnFields"] = new JObject
  270. {
  271. ["name"] = "姓名",
  272. ["sex"] = "性别",
  273. ["nation"] = "民族",
  274. ["birthday"] = "出生日期",
  275. ["idCode"] = "身份证号",
  276. ["address"] = "地址",
  277. ["department"] = "签发机关",
  278. ["startDate"] = "有效开始日期",
  279. ["endDate"] = "有效截止日期",
  280. ["sexCode"] = "性别代码",
  281. ["nationCode"] = "民族代码",
  282. ["certType"] = "证件类别"
  283. },
  284. ["notes"] = new JArray
  285. {
  286. "华视读卡器独立于医保业务,不影响SSCard.dll和NationECCode.dll的使用",
  287. "支持自动初始化:首次调用readcard/continuous/status时会自动初始化设备",
  288. "支持异常自愈:设备异常时会自动重置,下次调用时重新初始化",
  289. "手动初始化:可选择手动调用init接口指定特定端口",
  290. "需要部署termb.dll、sdtapi.dll、WltRs.dll、SysInfo.dll四个DLL文件",
  291. "卡认证循环间隔建议大于300ms",
  292. "查询卡片放置状态间隔建议大于600ms",
  293. "连续读卡模式可避免频繁拿起放下卡片",
  294. "现在使用起来和SSCard.dll一样简单:直接调用readcard即可"
  295. }
  296. };
  297. return Ok(help);
  298. }
  299. /// <summary>
  300. /// 健康检查
  301. /// </summary>
  302. /// <returns>服务健康状态</returns>
  303. [HttpGet]
  304. [Route("readcard/huashi/health")]
  305. public IHttpActionResult HealthCheck()
  306. {
  307. var health = new JObject
  308. {
  309. ["service"] = "华视电子读卡器API",
  310. ["status"] = "运行中",
  311. ["timestamp"] = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  312. ["version"] = "1.0.0"
  313. };
  314. return Ok(health);
  315. }
  316. /// <summary>
  317. /// GET方式的简单调用接口(兼容现有URL调用模式)
  318. /// </summary>
  319. /// <param name="action">操作类型:init、readcard、continuous、status、close</param>
  320. /// <param name="port">端口号(仅用于init操作)</param>
  321. /// <returns>操作结果</returns>
  322. [HttpGet]
  323. [Route("readcard/huashi/simple")]
  324. public IHttpActionResult SimpleCall(string action = "readcard", int port = 1001)
  325. {
  326. try
  327. {
  328. JObject result;
  329. switch (action?.ToLower())
  330. {
  331. case "init":
  332. result = HuaShiIdCardBusiness.Initialize(port);
  333. break;
  334. case "readcard":
  335. result = HuaShiIdCardBusiness.ReadIdCard("", true);
  336. break;
  337. case "continuous":
  338. // SimpleCall也是URL调用,应该启用自动关闭
  339. result = HuaShiIdCardBusiness.ReadIdCardContinuous("", true);
  340. break;
  341. case "status":
  342. result = HuaShiIdCardBusiness.GetDeviceStatus();
  343. break;
  344. case "close":
  345. result = HuaShiIdCardBusiness.Close();
  346. break;
  347. default:
  348. result = new JObject
  349. {
  350. ["code"] = 1001,
  351. ["message"] = $"不支持的操作:{action},支持的操作:init、readcard、continuous、status、close",
  352. ["device"] = "华视电子身份证读卡器"
  353. };
  354. break;
  355. }
  356. if ((int)result["code"] == 200)
  357. {
  358. return Ok(result);
  359. }
  360. else
  361. {
  362. return BadRequest(result.ToString());
  363. }
  364. }
  365. catch (Exception ex)
  366. {
  367. var errorResult = new JObject
  368. {
  369. ["code"] = 1001,
  370. ["message"] = $"华视读卡器操作异常: {ex.Message}",
  371. ["device"] = "华视电子身份证读卡器"
  372. };
  373. return BadRequest(errorResult.ToString());
  374. }
  375. }
  376. }
  377. }