exam-system/src/main/java/com/gkhy/exam/pay/controller/PayFeesController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
exam-system/src/main/java/com/gkhy/exam/pay/dto/rep/CoalPayRepDto.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
exam-system/src/main/resources/mapper/pay/CoalPayStudentMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/resources/application-dev.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/main/resources/application-pro.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ruoyi-admin/src/test/java/com/ruoyi/TestEncrypt.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
exam-system/src/main/java/com/gkhy/exam/pay/controller/PayFeesController.java
@@ -3,6 +3,7 @@ import com.alibaba.fastjson2.JSONObject; import com.gkhy.exam.pay.utils.PayUtils; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; import io.swagger.annotations.Api; import org.springframework.web.bind.annotation.PostMapping; @@ -20,6 +21,7 @@ @PostMapping("/inform") @Anonymous public Map<String,String> inform(@RequestBody JSONObject jsonObject){ PayUtils payUtils = new PayUtils(); Map<String, String> receive = null; exam-system/src/main/java/com/gkhy/exam/pay/dto/rep/CoalPayRepDto.java
@@ -71,7 +71,7 @@ */ private Integer totalNum; /** * 未交费数量 * 已交费数量 */ private Integer havePayNum; exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java
@@ -12,6 +12,7 @@ import com.gkhy.exam.pay.service.CoalPayStudentService; import com.gkhy.exam.pay.utils.PayUtils; import com.gkhy.exam.pay.utils.ResultVo; import com.gkhy.exam.pay.utils.Sign; import com.ruoyi.common.constant.ResultConstants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysDept; @@ -20,6 +21,7 @@ import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDeptMapper; import org.dom4j.Element; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; @@ -80,7 +82,7 @@ //学员数据 List<CoalPayStudent> coalPayStudents = coalPayStudentService.selectByCoalPayId(pay.getId()); List<CoalPayStudent> havePay = coalPayStudents.stream() .filter(stu -> stu.getPayStatus() != null && stu.getPayStatus().equals(1)) .filter(stu -> stu.getPayStatus() != null && stu.getPayStatus()==1) .collect(Collectors.toList()); coalPayRepDto.setTotalNum(coalPayStudents.size()); coalPayRepDto.setHavePayNum(havePay.size()); @@ -184,6 +186,7 @@ for (CoalPayStudent payStudent : coalPayStudents) { //封装学生基础信息 CoalPayStudentRep coalPayStudentRep = new CoalPayStudentRep(); coalPayStudentRep.setId(payStudent.getId()); coalPayStudentRep.setName(payStudent.getName()); coalPayStudentRep.setIdCard(payStudent.getIdCard()); coalPayStudentRep.setPhone(payStudent.getPhone()); @@ -249,6 +252,11 @@ ResultVo resultVo = payUtils.sendApiPost(payReqData); if (resultVo.getRespcode().equals("BUS0000")) { //进行票据签名并校验 ResultVo resultVo1 = payUtils.uploadXml(resultVo.getRespdata().getOrderNo(), resultVo.getRespdata().getFileData()); if (!resultVo1.getRespcode().equals("BUS0000")){ throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "签名验证错误"); } payStudent.setId(studentId); payStudent.setOrderId(resultVo.getRespdata().getOrderNo()); payStudent.setGovPayStatus(1); exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java
@@ -29,6 +29,9 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; @@ -36,8 +39,11 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; @@ -67,6 +73,9 @@ @Value("${finance.queryUrl}") private String queryUrl; @Value("${finance.uploadXmlUrl}") private String uploadXmlUrl; /** * 请求开票,发起支付 * @param payReqData @@ -92,6 +101,7 @@ HttpResultVo execute = httpClient.execute(httpPost, getResponseHandler()); String stringContent = execute.getStringContent(); ResultVo resultVo = JSONObject.parseObject(stringContent, ResultVo.class); log.info("请求结果为:"+resultVo); return resultVo; } @@ -337,4 +347,60 @@ return ResponseEntity.ok(result); } //上传财政电子票据签名文件 public ResultVo uploadXml(String orderId, String plain) throws IOException { Map<String, String> params = new HashMap<>(); Sign sign = new Sign(); Element signature = sign.getSignature(plain); JSONObject jsonObject = new JSONObject(); jsonObject.put("orderNo",orderId); jsonObject.put("fileData", Base64.getEncoder().encodeToString(convertElementToByteArray(signature))); String reqdata = Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes()); String mac = appId+"||" +reqdata; mac = DigestUtils.md5Hex(mac.getBytes()); params.put("appid",appId); params.put("reqdata",reqdata); params.put("mac",mac); HttpPost httpPost = new HttpPost(uploadXmlUrl); httpPost.setEntity(assemblyFormEntity(params,"utf-8")); HttpClient httpClient = getHttpClient(uploadXmlUrl); HttpResultVo execute = httpClient.execute(httpPost, getResponseHandler()); String stringContent = execute.getStringContent(); ResultVo resultVo = JSONObject.parseObject(stringContent, ResultVo.class); log.info("请求结果转为:"+resultVo); return resultVo; } //获取XML文件字节码 public static byte[] convertElementToByteArray(Element element) { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { // 设置输出格式 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); // 设置编码为UTF-8 // 创建 XMLWriter XMLWriter writer = new XMLWriter(new OutputStreamWriter(byteArrayOutputStream, StandardCharsets.UTF_8), format); // 写入 Element 对象 writer.write(element.getDocument()); writer.close(); // 关闭 writer,确保所有数据都被写入 } catch (IOException e) { e.printStackTrace(); // 打印异常信息 // 处理异常,比如返回一个空的字节数组或重新抛出异常 return new byte[0]; } // 返回字节数组 return byteArrayOutputStream.toByteArray(); } } exam-system/src/main/resources/mapper/pay/CoalPayStudentMapper.xml
@@ -70,8 +70,6 @@ <if test="govPayStatus!=null">gov_pay_status=#{govPayStatus},</if> <if test="updateBy != null">update_by = #{updateBy},</if> <if test="updateTime != null">update_time = #{updateTime},</if> <if test="createBy != null">create_by = #{createBy},</if> <if test="createTime != null">create_time = #{createTime},</if> <if test="delFlag != null">del_flag = #{delFlag},</if> </trim> where id = #{id} ruoyi-admin/src/main/resources/application-dev.yml
@@ -138,3 +138,4 @@ payNotifyUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/notifyConfirm.do payQueryUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/query.do queryUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/queryFile.do uploadXmlUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/uploadXml.do ruoyi-admin/src/main/resources/application-pro.yml
@@ -136,4 +136,5 @@ orderUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/invoice.do payNotifyUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/notifyConfirm.do payQueryUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/query.do queryUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/queryFile.do queryUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/queryFile.do uploadXmlUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/uploadXml.do ruoyi-admin/src/test/java/com/ruoyi/TestEncrypt.java
对比新文件 @@ -0,0 +1,131 @@ package com.ruoyi; import com.alibaba.fastjson2.JSONObject; import com.gkhy.exam.institutionalaccess.model.req.ThCertReqDTO; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.ResultConstants; import com.ruoyi.common.exception.BusinessException; import lombok.extern.log4j.Log4j2; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.UUID; @RunWith(SpringRunner.class) @SpringBootTest(classes = RuoYiApplication.class) @ActiveProfiles("dev") @Log4j2 public class TestEncrypt { private static final String key="Bd26jqDDJcdnBocn"; private static final String iv ="oVKRQCjElggSbd8D"; /** * 加密 */ @Test public void text001(){ //加密 List<ThCertReqDTO> thCertDTOs=new ArrayList<>(); ThCertReqDTO thCertDTO = new ThCertReqDTO(); thCertDTO.setUuid(UUID.randomUUID().toString()); JSONObject jsonObject = new JSONObject(); thCertDTO.setName("王五"); thCertDTO.setIdcard("123456789012345679"); thCertDTO.setBatchUuid("1ef0b81f-dcb7-62a9-ad8f-63e252089bc8"); thCertDTO.setTrainOrgName("1234567890123"); thCertDTO.setCertTime(LocalDateTime.now()); thCertDTO.setCertUrl("https://p26.toutiaoimg.com/origin/tos-cn-i-qvj2lq49k0/22f10850c5234b5285350743cfa16357"); thCertDTOs.add(thCertDTO); String jsonString = JSONObject.toJSONString(thCertDTOs); String encrypt = encrypt(jsonString); log.info("加密后为:"+encrypt); //解密 String decrypt = ""; try { decrypt = decrypt(encrypt); }catch (Exception e){ throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL); } log.info("解密后为:"+decrypt); } @Test public void dec(){ String mes = "nCVoBsCqZnKKYg0NBnsUPgjZpienDHaThN+mIcdcK9IhbjCEZj+ePQJUyLqXWY5+On7OiaCBPbdpx9NbsmR/IbIz0eVhh0BuI0iwbsB5vxkFd0LQHb8GkIM0aqMjwgQLHb1QQKYgne3Nh6/GsOlFveYQJPwiwXfdzsd/zKeWM6gohNBYuXDHAkwTboq/L7TFDVjTNfbvsu8pCVc0txoFmOTkvq5JUCsqBk4RvmM/AZ+yZjTCYkzkufg/sF5CFpbr36nCOzCGGJc1/+wm2qREzzC0HUxinhsXoMm6qJqa7/M3XDjWh/t6SDtxlzBLEgUcyEj2FL7vWLG9oB7EsnExcuY5YpQxJG45qGY6y9kYDF/swQaPsPIpGJhtczamAZuwi/DHuGWJsxqEWyWVEIc80gRek59j0vBMAmn/QVVP3Zu+qtxbJKRY0BAEaNKvIb66"; String decrypt = ""; try { decrypt = decrypt(mes); }catch (Exception e){ throw new BusinessException(this.getClass(), ResultConstants.THREE_INSTITUTION_PARAMM_NULL); } log.info("解密后为:"+decrypt); } private String decrypt(String data) { try { byte[] encryptCode = Base64.getDecoder().decode(data);//先用base64解密 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); byte[] original = cipher.doFinal(encryptCode); String originalString = new String(original); return originalString.trim(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } private String encrypt(String data){ try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); int blockSize = cipher.getBlockSize(); byte[] dataBytes = data.getBytes(Constants.UTF8); int plaintextLength = dataBytes.length; if (plaintextLength % blockSize != 0) { plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); } byte[] plaintext = new byte[plaintextLength]; System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); // CBC模式,需要一个向量iv,可增加加密算法的强度 cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); byte[] encrypted = cipher.doFinal(plaintext); // BASE64做转码。 String aseEncode = Base64.getEncoder().encodeToString(encrypted); return aseEncode; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } }