From 9a041565e4e730a4d0e4c3a5797228d83fad7c63 Mon Sep 17 00:00:00 2001 From: “djh” <“3298565835@qq.com”> Date: 星期五, 14 二月 2025 11:09:51 +0800 Subject: [PATCH] 煤矿缴费修改 --- exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java | 83 +++++++++++++++++++- exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java | 20 ++-- ruoyi-admin/pom.xml | 1 exam-system/src/main/java/com/gkhy/exam/pay/controller/CoalPayController.java | 15 +++ exam-system/src/main/resources/cssconfig.properties | 104 ++++++++++++++++++++++++++ ruoyi-admin/src/main/resources/application-pro.yml | 2 6 files changed, 206 insertions(+), 19 deletions(-) diff --git a/exam-system/src/main/java/com/gkhy/exam/pay/controller/CoalPayController.java b/exam-system/src/main/java/com/gkhy/exam/pay/controller/CoalPayController.java index 882c968..57aad87 100644 --- a/exam-system/src/main/java/com/gkhy/exam/pay/controller/CoalPayController.java +++ b/exam-system/src/main/java/com/gkhy/exam/pay/controller/CoalPayController.java @@ -1,14 +1,19 @@ package com.gkhy.exam.pay.controller; +import com.alibaba.fastjson2.JSONObject; import com.gkhy.exam.pay.dto.rep.CoalPayRepDto; import com.gkhy.exam.pay.dto.rep.CoalPayStudentRep; import com.gkhy.exam.pay.dto.req.*; import com.gkhy.exam.pay.entity.CoalPayStudent; +import com.gkhy.exam.pay.entity.PayReqData; import com.gkhy.exam.pay.service.CoalPayService; +import com.gkhy.exam.pay.utils.PayUtils; +import com.gkhy.exam.pay.utils.ResultVo; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.RandomUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiOperation; @@ -16,6 +21,9 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; import java.util.List; @RestController @@ -110,6 +118,13 @@ + @PostMapping("/topay") + @Anonymous + @ApiOperation(value = "缴费测试") + public AjaxResult toPay() throws IOException { + return success(coalPayService.topay()); + } + } diff --git a/exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java b/exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java index a7ede06..d587e47 100644 --- a/exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java +++ b/exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java @@ -1,5 +1,9 @@ package com.gkhy.exam.pay.service.impl; +import cn.com.jit.new_vstk.Bean.EnvelopResult; +import cn.com.jit.new_vstk.Bean.SignResult; +import cn.com.jit.new_vstk.Bean.VerifyResult; +import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gkhy.exam.pay.dto.rep.CoalPayRepDto; import com.gkhy.exam.pay.dto.rep.CoalPayStudentRep; @@ -13,6 +17,7 @@ import com.gkhy.exam.pay.utils.PayUtils; import com.gkhy.exam.pay.utils.ResultVo; import com.gkhy.exam.pay.utils.Sign; +import com.gkhy.exam.pay.utils.SignDto; import com.ruoyi.common.constant.ResultConstants; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.entity.SysDept; @@ -21,6 +26,7 @@ import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDeptMapper; +import lombok.extern.slf4j.Slf4j; import org.dom4j.Element; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; @@ -32,13 +38,12 @@ import javax.annotation.Resource; import java.io.IOException; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; +import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @Service +@Slf4j public class CoalPayServiceImpl extends ServiceImpl<CoalPayMapper, CoalPay> implements CoalPayService { @Resource @@ -255,10 +260,10 @@ 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, "签名验证错误"); - } +// 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); @@ -317,6 +322,70 @@ } } + @Override + public SignResult topay() throws IOException { + PayReqData payReqData = new PayReqData(); + PayReqData.Feedata feedatas = new PayReqData.Feedata(); + + + //订单编号 + payReqData.setOrderNo(RandomUtil.generateOrderNumber(1L, "CO")); + //订单总金额 + payReqData.setMoney(BigDecimal.valueOf(56)); + //子订单数目 + payReqData.setAmount(1); + //缴费人姓名(单位填单位名称)阿克苏地区博安煤矿安全技术服务中心 + payReqData.setPayerName("阿克苏地区博安煤矿安全技术服务中心"); + //缴费人证件号(单位填同一信用代码)52652900789893140A + payReqData.setCertNo("52652900789893140A"); + //缴款人类型(1个人 2单位) + payReqData.setPayerType(2); + //开票单位社会信用代码12650000MB1A9612XD + payReqData.setInvoiceSocialCode("11650000MB1957293J"); + //开票人 + payReqData.setHandlingPerson("张三"); + //复核人 + payReqData.setChecker("李四"); + //单位编码547185129 + payReqData.setEnterCode("547185129"); + //订单描述(非必填) + payReqData.setDesc("煤矿安全作业理论考试-002002"); + //订单明细 + List<PayReqData.Feedata> feedatas1 = new ArrayList<>(); + //数量 +// feedatas.setAmount(1); +// //业务代码 +// feedatas.setBusCode("DZ12401"); +// //单价 +// feedatas.setPrice(BigDecimal.valueOf(56)); + PayReqData.Feedata feedata = new PayReqData.Feedata(); + feedata.setBusCode("DZ002002"); + feedata.setAmount(1); + feedata.setPrice(BigDecimal.valueOf(56)); +// feedatas1.add(feedatas); + feedatas1.add(feedata); + payReqData.setFeeDatas(feedatas1); + log.info("请求参数:"+ JSONObject.toJSONString(payReqData)); + + + PayUtils payUtils = new PayUtils(); + ResultVo resultVo = payUtils.sendApiPost(payReqData); + String jsonString = JSONObject.toJSONString(resultVo); + log.info("请求结果:"+jsonString); + String fileData = resultVo.getRespdata().getFileData(); + Base64.Decoder decoder = Base64.getDecoder(); + byte[] decode = decoder.decode(fileData); + SignResult sign = payUtils.sign(decode); + log.info("签名结果为:"+ Arrays.toString(sign.getSignData())); + VerifyResult verify = payUtils.verify(decode, new String(sign.getSignData())); + SignDto signDto = new SignDto("SM3", "Base64", new Date(), verify.getReturnData(), verify.getSerialNumber(), verify.getIssure()); + Sign sign1 = new Sign(); + Element signature = sign1.getSignature(signDto); + EnvelopResult envelopResult = payUtils.encryptEnvelop(String.valueOf(signature)); + log.info("制作数字信封为:"+ Arrays.toString(envelopResult.getEnvelopData())); + return sign; + } + private PayReqData fillData(List<CoalPayStudent> coalPayStudent, CoalPay coalPay, List<CoalCategory> coalCategories, CoalTicket coalTicket,Integer payType,CoalTeamPayReq coalTeamPayReq) { PayReqData payReqData = new PayReqData(); payReqData.setOrderNo(RandomUtil.generateOrderNumber(coalPay.getId(), "CO")); diff --git a/exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java b/exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java index f96042f..0c92d97 100644 --- a/exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java +++ b/exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java @@ -43,10 +43,7 @@ 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.io.*; import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; @@ -91,12 +88,13 @@ Map<String, String> param = new HashMap<>(); HttpPost httpPost = new HttpPost("http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/invoice.do"); - + log.info("请求地址:"+"http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/invoice.do"); //请求参数转为json格式base64编码 String reqData = Base64.getEncoder().encodeToString(JSONObject.toJSONString(payReqData).getBytes()); String mac = "ED76A5F1703540BE977D34780B371FEB" + "||" + reqData; mac = DigestUtils.md5Hex(mac.getBytes()); param.put("appid", "ED76A5F1703540BE977D34780B371FEB"); + log.info("请求appid:"+"ED76A5F1703540BE977D34780B371FEB"); param.put("reqdata", reqData); param.put("mac", mac); @@ -353,7 +351,7 @@ } //上传财政电子票据签名文件 - public ResultVo uploadXml(String orderId, String plain) throws IOException { + public ResultVo uploadXml(String orderId, byte[] plain) throws IOException { Map<String, String> params = new HashMap<>(); Sign sign = new Sign(); @@ -413,12 +411,12 @@ //签名 - public SignResult sign(String strData) { + public SignResult sign(byte[] strData) { SignResult result = null; String certId = "rsa"; try { AdvanceSignClient client = new AdvanceSignClient("cssconfig.properties"); - result = client.sign(certId,strData.getBytes()); + result = client.sign(certId,strData); log.info("***签名成功***"); byte[] signData = result.getSignData(); String s = new String(Base64.getEncoder().encode(signData)); @@ -435,11 +433,11 @@ /** * 验签名 */ - public VerifyResult verify(String strData,String signData){ + public VerifyResult verify(byte[] strData,String signData){ VerifyResult verify = null; try { - AdvanceSignClient client = new AdvanceSignClient("cssconfig.properties"); - byte[] plain = strData.getBytes(); + AdvanceSignClient client = new AdvanceSignClient("src/main/resources/cssconfig.properties"); + byte[] plain = strData; byte[] sign = signData.getBytes(); verify = client.verify(sign, plain); diff --git a/exam-system/src/main/resources/cssconfig.properties b/exam-system/src/main/resources/cssconfig.properties new file mode 100644 index 0000000..bb81eac --- /dev/null +++ b/exam-system/src/main/resources/cssconfig.properties @@ -0,0 +1,104 @@ +#ServerURL=http://127.0.0.1:8000/signxmlhandler +#ServerURL=http://127.0.0.1:8000/service/tsa +#ServerURL=http://127.0.0.1:8000/signserver/service/xml +ServerURL=http://192.168.0.110:8000 +DigestAlg=SM3 +#Encrypt Algorithm: des3/scb2 +EncAlg=SM4 +#\u5BF9\u79F0\u52A0\u89E3\u5BC6\u586B\u5145\u65B9\u5F0F\uFF1ANO_PADDING \u9ED8\u8BA4\u4E3APKCS7PADDING +SymmPadding= +#RSA\u7B97\u6CD5\u586B\u5145\u65B9\u5F0F\u652F\u6301PSS +signPadding= +#\u5BF9\u79F0\u7B97\u6CD5 RSA/SM2 +asymmalg=SM2 +#\u5370\u7AE0\u6807\u51C6 1:\u56FD\u6807/4:\u56FD\u529E +standard=1 +#\u6458\u8981\u7B97\u6CD5\u81EA\u9002\u5E94\u53C2\u6570 +P1VerfiyParserCert=0 +#\u6458\u8981\u7B97\u6CD5\uFF08\u56FD\u5BC6\u548CRSA\uFF09 +GMDigest=sm3 +P1VerifyRsaDefDigest=sha1 +CertBaseInfo=version;issuerdn;subjectdn;serialnumber;notbefore;notafter +TSACertBaseInfo=issuerdn;subjectdn;serialnumber;signedTime;signedTSA;signedTimeByMS +CertExtendInfo= +AppID= +CertAlias= +BaseInfo=digestalg;digestdata;plaindata;dscert +SendMsgFormat=0 +HashActionPosition=0 +PrintLog=false +#console/file/log4j ####log4j not implement +logTarget=console +logFilePath=/temp/jit.dss.vstk.log +#rfc3161/rfc2630 +TSAType=rfc3161 +#dsCert/issuerDNAndSN/CertId/fileDsCert +p1VerifyCertId=CertId +#dsCert/issuerDNAndSN/CertId/fileDsCert +encryptEnvelopCertId=CertId +#dsCert/issuerDNAndSN/CertId/fileDsCert +ebcerVerifyCertId=CertId +#dsCert/issuerDNAndSN/CertId/fileDsCert +pdfSignCertId=CertId +Compatible=true +dss.client.class=cn.com.jit.assp.client.DSSClientHttpUrlConnectionImpl +#dss.client.class=cn.com.jit.assp.client.DSSClientHttpClientImpl +#default/encAfterDec/secretEnvelop(use this mode after using VCTK do envelop) secretEnvelop:develop->RSAdecrypt->RSAencrypt->envelop +envelopType=default +#default unit KB and default size is 0,0 is not block; +packageSize=0 +communicationProtocol=1 +#default:10000 unit: ms +timeout=10000 +connectTimeOut=10000 +# default : system unicode +FileSystemCharSet=UTF-8 +vstkVersion=20 +EncryptMode=ecb +#package size every time, unit is byte 1047580 3142740 240000 +send_size=1048580 +#bigger than this will take big data modle, unit is byte +bigdata_limit=2097152000 +#first send request read_timeout +first_read_timeout=10000 + +#the path of cssconfig.properties; support absolutepath and relativepath +defaultConfigFile=./src/main/webapp/conf/cssconfig.properties +#true:Keep-Alive false:Close +connectionType=true +#the method run time(Millisecond) +runTime=100 +needXmlToPdf=true +une= +pwd= +aid=WeChat +#\u5E94\u6025\u5E7F\u64AD\u5C0F\u8BC1\u4E66\uFF08jnta\uFF09 +organization=jnta +tenantId= +#\u5236\u4f5c\u7b7e\u540d\u6216\u5236\u4f5c\u4fe1\u5c01\u7684\u7ed3\u679c\u662f\u5426\u4e3abase64\u683c\u5f0f.true:\u662f;false:\u5426. +isEncryptSignData=false +#\u5236\u4f5c\u7b7e\u540d\u6216\u5236\u4f5c\u4fe1\u5c01\u7684\u7ed3\u679c\u662f\u5426\u4e3a\u5e26\u6362\u884c\u7684base64\u683c\u5f0f.true:\u662f;false:\u5426. +#\u6bcf16\u5b57\u8282\u56de\u8f66\u6362\u884c\uff0c\u9700\u8981isEncryptSignData=true\u914d\u7f6e\u624d\u4f1a\u751f\u6548 +#\u6b64\u914d\u7f6e\u4ec5\u9650\u4e8e\u539f\u6587\u63a5\u53e3 +isEncryptSignDataWithCRLF=false +pdfVisibleSignature=true +applyId= +applyPwd= +userId= +userPwd= +#\u662F\u5426\u8BB0\u5F55\u9519\u8BEF\u65E5\u5FD7\u53C2\u6570 +record_error_log_params=false +sealInfo=sealName;sealPicture;validTime;asone +#\u505Amof\u4E1A\u52A1\u5206\u6D41\uFF0C\u9ED8\u8BA4\u4E0D\u586B\u5199\uFF0C\u8868\u793A\u517C\u5BB9\u8001\u7248\u672C\u8001\u6A21\u5F0F\uFF1B\u540E\u7EED\u7248\u672C\u53EF\u4EE5\u505A\u5206\u6D41\uFF0C\u5F53\u4E3Arsa mof\u4E1A\u52A1\u5219\u9700\u8981\u8BBE\u7F6E\u4E3Amof +mofFlow= +#demo-VSTK\u8BED\u8A00(en_US,zh_CN) +Language= +isOpenGmssl=false +#\u63E1\u624B\u534F\u8BAE(\u5BC6\u6587\u7AEF\u53E38003\u63E1\u624B\u534F\u8BAE\u76EE\u524D\u4EC5\u652F\u6301TLSv1,TLSv1.1,TLSv1.2 \u6B64\u53C2\u6570\u9700\u8981\u91CD\u542Fvstk) +ssl_protocal=TLSv1 +#\u4EC5\u652F\u6301\u586B\u5199OAEP\uFF0C\u4E0D\u586B\u5199\u65F6\u4F7F\u7528PKCS1\u586B\u5145#AsymmPadding=OAEPWITHSHA256AndMGF1Padding +AsymmPadding= +#\u4FE1\u4EFB\u6240\u6709\u8BC1\u4E66(\u5BC6\u6587\u8BF7\u6C42\u65F6\u53C2\u6570\uFF0C\u9ED8\u8BA4\u4E3A\u4FE1\u4EFBclient.keystore\u8BC1\u4E66) +TrustMaterialAll=false +#\u9A8C\u7B7E\u8BC1\u4E66\u8FD4\u56DE\u5B57\u6BB5 +HighCertBaseInfo=version;issuerdn;subjectdn \ No newline at end of file diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index cfe6fc6..8663e37 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -94,6 +94,7 @@ <version>2.5.15</version> <configuration> <fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> + <includeSystemScope>true</includeSystemScope> </configuration> <executions> <execution> diff --git a/ruoyi-admin/src/main/resources/application-pro.yml b/ruoyi-admin/src/main/resources/application-pro.yml index 01d99f1..e91fd5f 100644 --- a/ruoyi-admin/src/main/resources/application-pro.yml +++ b/ruoyi-admin/src/main/resources/application-pro.yml @@ -24,7 +24,7 @@ druid: # 主库数据源 master: - url: jdbc:mysql://127.0.0.1:7006/swspkmas?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true + url: jdbc:mysql://106.15.95.149:7006/swspkmas?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true username: root password: 2farwL3yPXfbH2AP # 从库数据源 -- Gitblit v1.9.2