CcbMisPosApi.java 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package thyyxxk.webserver.api.ccbmispos;
  2. import com.ccb.wlpt.RequestProcess;
  3. import lombok.extern.slf4j.Slf4j;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestParam;
  8. import org.springframework.web.bind.annotation.RestController;
  9. import thyyxxk.webserver.config.auth.PassToken;
  10. import thyyxxk.webserver.config.envionment.CcbMisConfig;
  11. import thyyxxk.webserver.config.exception.BizException;
  12. import thyyxxk.webserver.config.exception.ExceptionEnum;
  13. import thyyxxk.webserver.dao.his.api.CcbMisposDao;
  14. import thyyxxk.webserver.entity.ResultVo;
  15. import thyyxxk.webserver.utils.*;
  16. import java.io.IOException;
  17. import java.util.ArrayList;
  18. import java.util.List;
  19. import java.util.Objects;
  20. import java.util.Queue;
  21. @Slf4j
  22. @RestController
  23. @RequestMapping("/api/ccbmispos")
  24. public class CcbMisPosApi {
  25. private volatile boolean initialized = false;
  26. private final CcbMisConfig cfg;
  27. private final CcbMisposDao dao;
  28. @Autowired
  29. public CcbMisPosApi(CcbMisConfig cfg, CcbMisposDao dao) {
  30. this.cfg = cfg;
  31. this.dao = dao;
  32. }
  33. @PassToken
  34. @GetMapping("/initFileCert")
  35. public String initFileCert() {
  36. log.info("initFileCert:{}", cfg);
  37. String initResult = RequestProcess.initFileCert(cfg.getMchId(), cfg.getUserid(),
  38. cfg.getCertFile(), cfg.getCertPassword(), cfg.getConfigFile());
  39. if (Objects.equals(initResult, "")) {
  40. initResult = "INIT SUCCESS";
  41. initialized = true;
  42. } else {
  43. initialized = false;
  44. initResult = "INIT FAILED:" + initResult;
  45. }
  46. log.info("initResult:{}", initResult);
  47. return initResult;
  48. }
  49. @PassToken
  50. @GetMapping("/removeFileCert")
  51. public String removeFileCert() {
  52. RequestProcess.removeFileCert(cfg.getMchId(), cfg.getUserid());
  53. return "OK";
  54. }
  55. @PassToken
  56. @GetMapping("/downloadTradeList")
  57. public ResultVo<String> downloadTradeList(@RequestParam("date") String date) throws IOException {
  58. // date 应是 yyyyMMdd 格式:20250903
  59. if (date.contains("-")) {
  60. date = date.replaceAll("-", "");
  61. }
  62. if (!initialized) {
  63. String initResult = initFileCert();
  64. if (!Objects.equals(initResult, "INIT SUCCESS")) {
  65. throw new BizException(ExceptionEnum.LOGICAL_ERROR, "初始化证书失败:" + initResult);
  66. }
  67. }
  68. String xml = "<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?> \n" +
  69. "<TX> \n" +
  70. " <REQUEST_SN>" + System.currentTimeMillis() + "000</REQUEST_SN> \n" +
  71. " <CUST_ID>"+cfg.getMchId() +"</CUST_ID> \n" +
  72. " <USER_ID>"+cfg.getUserid()+"</USER_ID> \n" +
  73. " <PASSWORD>"+cfg.getUserPassword()+"</PASSWORD> \n" +
  74. " <TX_CODE>5W1005</TX_CODE> \n" +
  75. " <LANGUAGE>CN</LANGUAGE> \n" +
  76. " <TX_INFO> \n" +
  77. " <DATE>" + date + "</DATE> \n" +
  78. " <KIND>1</KIND> \n" +
  79. " <FILETYPE>1</FILETYPE> \n" +
  80. " <TYPE>0</TYPE> \n" +
  81. " <NORDERBY>1</NORDERBY> \n" +
  82. " <POS_CODE></POS_CODE> \n" +
  83. " <ORDER></ORDER> \n" +
  84. " <STATUS>1</STATUS> \n" +
  85. " <BILL_FLAG>1</BILL_FLAG> \n" +
  86. " <Mrch_No></Mrch_No> \n" +
  87. " <GROUP_FLAG>0</GROUP_FLAG> \n" +
  88. " <TXN_TPCD>1</TXN_TPCD> \n" +
  89. " </TX_INFO>\n" +
  90. "</TX> \n";
  91. log.info("入参:\r\n{}", xml);
  92. String result = RequestProcess.sendRequest(cfg.getServiceUrl(), xml);
  93. log.info("出参:\r\n{}", result);
  94. String code = analyzeCodeValue(result);
  95. if (code.equals("000000")) {
  96. String fileName = result.split("<FILE_NAME>")[1]
  97. .split("</FILE_NAME>")[0];
  98. log.info("fileName: {}", fileName);
  99. return downloadFile(fileName);
  100. }
  101. String errMsg = result.split("<RETURN_MSG>")[1]
  102. .split("</RETURN_MSG>")[0];
  103. throw new BizException(ExceptionEnum.LOGICAL_ERROR, errMsg);
  104. }
  105. private ResultVo<String> downloadFile(String fileName) throws IOException {
  106. String xml = "<?xml version=\"1.0\" encoding=\"GB2312\" standalone=\"yes\" ?> \n" +
  107. "<TX> \n" +
  108. " <REQUEST_SN>" + System.currentTimeMillis() + "000</REQUEST_SN> \n" +
  109. " <CUST_ID>"+cfg.getMchId() +"</CUST_ID> \n" +
  110. " <USER_ID>"+cfg.getUserid()+"</USER_ID> \n" +
  111. " <PASSWORD>"+cfg.getUserPassword()+"</PASSWORD> \n" +
  112. " <TX_CODE>6W0111</TX_CODE> \n" +
  113. " <LANGUAGE>CN</LANGUAGE> \n" +
  114. " <TX_INFO> \n" +
  115. " <SOURCE>" + fileName + "</SOURCE> \n" +
  116. " <FILEPATH>merchant/shls</FILEPATH> \n" +
  117. " <LOCAL_REMOTE>0</LOCAL_REMOTE> \n" +
  118. " </TX_INFO> \n" +
  119. "</TX> \n";
  120. log.info("入参:\r\n{}", xml);
  121. String result = RequestProcess.downloadFile(cfg.getServiceUrl(), xml, cfg.getFileDir());
  122. log.info("出参:\r\n{}", result);
  123. String code = analyzeCodeValue(result);
  124. if (code.equals("000000")) {
  125. unzipFile(fileName);
  126. return ResultVoUtil.success("下载文件成功");
  127. }
  128. String errMsg = result.split("<RETURN_MSG>")[1]
  129. .split("</RETURN_MSG>")[0];
  130. throw new BizException(ExceptionEnum.LOGICAL_ERROR, errMsg);
  131. }
  132. private void unzipFile(String zipFileName) throws IOException {
  133. String txtPath = ZipUtil.unZip(zipFileName, cfg.getFileDir(), ".det.");
  134. Queue<String> queue = SiUtil.readTxtFile(txtPath);
  135. List<CcbMisposPaymentRecord> recordList = new ArrayList<>();
  136. if (!queue.isEmpty()) {
  137. queue.poll();
  138. }
  139. if (!queue.isEmpty()) {
  140. String textLine = queue.poll();
  141. CcbMisposPaymentRecord record = makeRecordFromText(textLine);
  142. recordList.add(record);
  143. String date = textLine.split("\\|")[4];
  144. String begin = date + " 00:00:00";
  145. String end = date + " 23:59:59";
  146. dao.deleteDuplicateData(begin, end);
  147. }
  148. while (!queue.isEmpty()) {
  149. String textLine = queue.poll();
  150. CcbMisposPaymentRecord record = makeRecordFromText(textLine);
  151. recordList.add(record);
  152. if (recordList.size() == 30) {
  153. dao.insert(recordList);
  154. recordList.clear();
  155. }
  156. }
  157. if (!recordList.isEmpty()) {
  158. dao.insert(recordList);
  159. }
  160. ZipUtil.deleteFile(txtPath);
  161. ZipUtil.deleteFile(cfg.getFileDir() + zipFileName);
  162. }
  163. private String analyzeCodeValue(String resultXml) {
  164. if (resultXml.contains("<RETURN_CODE>") && resultXml.contains("</RETURN_CODE>")) {
  165. return resultXml.split("<RETURN_CODE>")[1].split("</RETURN_CODE>")[0];
  166. }
  167. throw new BizException(ExceptionEnum.NULL_POINTER, "返回值异常,没有 <RETURN_CODE> 节点。");
  168. }
  169. private CcbMisposPaymentRecord makeRecordFromText(String txt) {
  170. String[] arr = txt.split("\\|");
  171. CcbMisposPaymentRecord record = new CcbMisposPaymentRecord();
  172. record.setId(SnowFlakeId.instance().nextId());
  173. record.setTerminalNo(arr[0]);
  174. record.setCardBelong(arr[1]);
  175. record.setCardType(arr[2]);
  176. record.setCardSerialNo(arr[3]);
  177. String timeStr = arr[4] + " " + arr[5];
  178. record.setTradeTime(DateUtil.parse(timeStr));
  179. record.setTradeType(arr[6]);
  180. record.setGrantNo(arr[7]);
  181. record.setTradeAmount(arr[8]);
  182. record.setBankHandlingFee(arr[9]);
  183. record.setReceivedAmount(arr[10]);
  184. record.setTraceNo(arr[11]);
  185. record.setBatchNo(arr[12]);
  186. record.setPosTradeSort(arr[13]);
  187. record.setSettleAccount(arr[14]);
  188. record.setTradeNo(arr[15]);
  189. record.setPosNo(arr[16]);
  190. record.setSystemReferNo(arr[17]);
  191. record.setPaymentVoucher(arr[18]);
  192. record.setRemark1(arr[19]);
  193. record.setRemark2(arr[20]);
  194. record.setOrderAmount(arr[21]);
  195. return record;
  196. }
  197. }