BE_Call_DownloadBillFile.groovy 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. import Ignore_ReadUTF8File as ReadUTF8File
  2. import com.dySweetFishPlugin.tool.crypto.encoder.BASE64Decoder
  3. import com.sweetfish.convert.json.JsonConvert
  4. import com.sweetfish.service.RetResult
  5. import com.yinjie.heating.common.api.BusinessExecutor
  6. import com.yinjie.heating.common.datas.ERPModule
  7. import com.yinjie.heating.common.entity.base.ProcessMapItem
  8. import com.yinjie.heating.common.entity.callthird.DownloadBillResponse
  9. import com.yinjie.heating.common.entity.heating.HeatingApp
  10. import com.yinjie.heating.common.tool.PaySignatureUtil
  11. import org.apache.commons.lang3.StringUtils
  12. import org.apache.logging.log4j.LogManager
  13. import org.apache.logging.log4j.Logger
  14. import org.rex.RMap
  15. import javax.annotation.Resource
  16. import javax.crypto.Cipher
  17. import javax.crypto.KeyGenerator
  18. import javax.crypto.SecretKey
  19. import javax.crypto.spec.IvParameterSpec
  20. import java.nio.file.Files
  21. import java.nio.file.Path
  22. import java.nio.file.Paths
  23. import java.security.KeyFactory
  24. import java.security.PublicKey
  25. import java.security.SecureRandom
  26. import java.security.spec.X509EncodedKeySpec
  27. import java.time.LocalDateTime
  28. class BE_Call_DownloadBillFile implements BusinessExecutor<ProcessMapItem, DownloadBillResponse> {
  29. private final Logger logger = LogManager.getLogger(this.getClass().getSimpleName())
  30. @Resource
  31. private JsonConvert jsonConvert
  32. @Resource(name = "property.downloadBillRoot")
  33. private String downloadBillRoot
  34. @Override
  35. String scriptName() {
  36. return "外部热力服务商调用-下载对账单,需加密"
  37. }
  38. @Override
  39. ERPModule module() {
  40. return ERPModule.CALL_THIRD
  41. }
  42. private static byte[] encryptFile(SecretKey aesKey, byte[] fileData) throws Exception {
  43. // 生成随机的16字节初始化向量 (IV)
  44. byte[] iv = new byte[16];
  45. new SecureRandom().nextBytes(iv);
  46. IvParameterSpec ivSpec = new IvParameterSpec(iv);
  47. Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  48. cipher.init(Cipher.ENCRYPT_MODE, aesKey, ivSpec);
  49. // 将IV和加密后的数据一起返回,IV不需要保密,但需要用于解密
  50. byte[] encryptedData = cipher.doFinal(fileData);
  51. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  52. outputStream.write(iv);
  53. outputStream.write(encryptedData);
  54. return outputStream.toByteArray();
  55. }
  56. private static byte[] encryptAESKey(String publicKeyStr, SecretKey aesKey) throws Exception {
  57. byte[] keyBytes = (new BASE64Decoder()).decodeBuffer(publicKeyStr);
  58. X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
  59. KeyFactory keyFactory = KeyFactory.getInstance("RSA");
  60. PublicKey publicKey = keyFactory.generatePublic(keySpec);
  61. Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  62. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  63. return cipher.doFinal(aesKey.getEncoded());
  64. }
  65. RetResult<DownloadBillResponse> execute(ProcessMapItem source) {
  66. long currentTime = LocalDateTime.now().toDate().time
  67. RMap params = source.itemData
  68. String dataSourceId = source.dataSourceId
  69. long supplierCode = source.supplierCode
  70. String payDate = params.getString("payDate")
  71. HeatingApp app = params.get("app") as HeatingApp
  72. params.remove("app")//避免影响下面验签
  73. //接口均返回正确,错误放在result里
  74. if (app == null) {
  75. logger.error("下载对账单传入app为空")
  76. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  77. .respCode("DEF0010")
  78. .respMsg("用户不存在")
  79. .timeStamp((new Date()).time as String)
  80. .build())
  81. }
  82. if (StringUtils.isBlank(payDate)) {
  83. logger.error("下载对账单传入参数不正确")
  84. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  85. .respCode("DEF0006")
  86. .respMsg("系统错误")
  87. .timeStamp((new Date()).time as String)
  88. .build())
  89. }
  90. //签名
  91. String sign = params.getString("sign")
  92. if (PaySignatureUtil.verifySign(sign, "RSA_1_256", params, app.supplyPublicKey, "")) {
  93. logger.info("下载对账单验签成功")
  94. //查找对应日期的文件夹是否存在
  95. Path dirPath = Paths.get(downloadBillRoot + File.separator + payDate)
  96. if (Files.exists(dirPath) && (Files.isDirectory(dirPath))) {
  97. Path filePath = Paths.get(downloadBillRoot + File.separator + payDate + File.separator + "GD_" + payDate + "_" + app.upperChannelAppId + ".txt")
  98. if (Files.exists(filePath)) {
  99. //读取文件内容并加密
  100. KeyGenerator keyGenerator = KeyGenerator.getInstance("AES")
  101. keyGenerator.init(128) // 使用128位密钥长度
  102. SecretKey aesKey = keyGenerator.generateKey()
  103. String fileStr = ReadUTF8File.execute(filePath, false, logger)
  104. byte[] fileData = fileStr.getBytes("UTF-8")
  105. byte[] encryptedFileData = encryptFile(aesKey, fileData) //加密的文件
  106. byte[] encryptedAESKey = encryptAESKey(app.supplyPublicKey, aesKey) //加密的密钥
  107. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  108. .respCode("00000")
  109. .respMsg("success")
  110. .appId(app.appId)
  111. .fileKey(encryptedAESKey)
  112. .fileContent(encryptedFileData)
  113. .timeStamp((new Date()).time as String)
  114. .build())
  115. } else {
  116. logger.error("找不到对账单" + filePath.toString())
  117. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  118. .respCode("DEF0020")
  119. .respMsg("该日期账单文件暂未生成")
  120. .timeStamp((new Date()).time as String)
  121. .build())
  122. }
  123. } else {
  124. logger.error("找不到对账单日期" + payDate + "的目录")
  125. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  126. .respCode("DEF0020")
  127. .respMsg("该日期账单文件暂未生成")
  128. .timeStamp((new Date()).time as String)
  129. .build())
  130. }
  131. } else {
  132. logger.error("下载对账单验签失败")
  133. return RetResult.<DownloadBillResponse> successT().result(new DownloadBillResponse.Builder()
  134. .respCode("DEF0030")
  135. .respMsg("验签失败")
  136. .timeStamp((new Date()).time as String)
  137. .build())
  138. }
  139. }
  140. }