Sfoglia il codice sorgente

完成开票时变更明细记录的企业名称

lzm 3 anni fa
parent
commit
ecc16c1621

+ 88 - 0
sp-server/src/main/java/com/pj/api/pushfee/Demo.java

@@ -0,0 +1,88 @@
+package com.pj.api.pushfee;
+
+import cn.hutool.core.date.DateUtil;
+import com.pj.api.pushfee.tools.EncryptTools;
+import tools.http.HttpUtils;
+import com.pj.api.pushfee.tools.message.MessageInter;
+import com.pj.api.pushfee.tools.message.api.OdsOrderPayDetailDTO;
+import com.pj.api.pushfee.tools.message.api.OrderPayDetailMessage;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 1. 生成公私钥的方法:EncryptTools.generateKeyPairs
+ */
+public class Demo {
+
+    //客户端公私钥
+    public static final String f_remotePublicKeyBase6 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCb5yK85EKqwiQU+z1jyjOng6ecssQpEjC6STbCuSWN6KHLkijBxdqrCumXhbIyOVx4lHK9Rg5EjzlQxoaXQTgJdItaGjLC+UTE+NNAnnaFLg0x4jajNpLo473zdZxTYQaT3q/aKnTeXuKHw11PPUe4hmmfxPcdt9yJ0Iqo/XxV3QIDAQAB";
+    public static final String f_remotePrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJvnIrzkQqrCJBT7PWPKM6eDp5yyxCkSMLpJNsK5JY3oocuSKMHF2qsK6ZeFsjI5XHiUcr1GDkSPOVDGhpdBOAl0i1oaMsL5RMT400CedoUuDTHiNqM2kujjvfN1nFNhBpPer9oqdN5e4ofDXU89R7iGaZ/E9x233InQiqj9fFXdAgMBAAECgYASoeKgcaVYFCDM0yQIn5thy1XGYAUapX5mXSaqygbneWSQ2FR/qB5Ur9awEb30y682CAPYhB1jazyd30QpopVINvyhaWhgq1b/8KD92FqOg1eXxa7bTuTe8aMuKTB/ZJjEry0d5Mu3i6zYKtTSbnpnag5I3UE5awLDy7utYOoOHwJBAPtvz2ZBhtJvL3lsMgs7kGqrPqqI2LAX8J3oOCtE/6eQjQ0I5fBCybrwHp3baDrYul5KTL3kJvl4iWN/gHDi/nMCQQCeu3gzy0DVtM8M8bzFc/ZA753WRn4Z5axQa6lE7Tski8TUw4Bhbfan9E/C6l6Guo/+2hXPAE/RMcncClqeXXZvAkEAgf6FsO1x4fxABDvvB6Ws/ak5hfuoZCqMaWd1GtHah2yRsEqIbxZoq7CXc6/LDJmeiT9Ku+ZoTBSIm5uA8Vw6hwJALEbs872pmzMxYlH4Lzf2pAxzAbduK3kmhNRTRjfKfJpEUHksUYEkAZujuCI6NejKi/N3i+NxYFA8F5YHyw8VHwJAWoiYSYLSziHgDytoPKFvUp6EKLGDClhACJKc4LuaPNWICMxb5Dp88sY0NDYb4HzCyWIE5G4vbiF/K3kEEwCIVA==";
+
+    //服务端公私钥
+    public static final String f_localPublicKeyBase6 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCimSu5J8apt2YR/o9joOCNdFzO3rOHcdcqnSCm1Wt19VwskTVjkKHc/CXHUoskX5vMiMiv6xPnf/lDpMO6KnCrwlVQFtbPvmnkwyUs/haW8ggR865MqDcBpdMGnuV0YJ04UXxSrOX+eu+dl91Web4/ZiRKbObOa8WhFm/Ln2QKswIDAQAB";
+    public static final String f_localPrivateKeyBase6 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKKZK7knxqm3ZhH+j2Og4I10XM7es4dx1yqdIKbVa3X1XCyRNWOQodz8JcdSiyRfm8yIyK/rE+d/+UOkw7oqcKvCVVAW1s++aeTDJSz+FpbyCBHzrkyoNwGl0wae5XRgnThRfFKs5f56752X3VZ5vj9mJEps5s5rxaEWb8ufZAqzAgMBAAECgYAmP/QaLXI9kIgxaXnfzQOmIx6GB7uh/DTKsIXy2TfbWunhDhPKJUb+jk5w0kkrOFaVSgQz5hAboG5J7GOi0sMINLb7H2WsOm3uGM/8HPZYsrNFnB8VUiD26LIZ6+HhPXfp/LN+k5eUnUlD6z/dZU1k6hJPOSFC3PyzfBWqaQMqGQJBAMVdQ9Uw+eC94qD1MSSEQZhqpfGE4vO7WrSACLFqyZrHvaIwZTjdUZRF1aMlJyT0afOkfSN/53QQEcejXMUrSBcCQQDS576SXkpdfrN2jmr9BAimi+6AP71GUgXL3O+2yRL2szLoU7GwtMREPBFw+ocnC4UN87NCYveJCzenQEt48JfFAkAqEIa0mYuoatAyng+rSMTyR0i3ASud5wCeF+vCZJAzfP7d4pKwW/tXLsspynFdXvp2A0jomAosooAnnJnZLDBhAkBzXoXm92Fip45wShPIeE5rHJzI1xUoxHGbRS50JKYVAY3VfQL0kM3ULa+0x7bq6uhL64WhyRVziAlXmlouvB2pAkEAuDvsjVhdo3uMGL7Tr+igPhajoWUTjPuAf+Od3SsqMTPFLBpbJM8ziXk39Me9S8wqgGwR3pnlC1Z6Rybgm+uy4g==";
+
+
+    public static void main(String[] args) {
+
+
+        testMessage();
+//        testEncrypt();
+
+
+    }
+
+    private static void testMessage(){
+        String msg = "{\"header\":{\"sysId\":\"hd\",\"encrypted\":\"Tt2mAxr7pXtIOiRl8zJ/+wXlvgxH21qhLjhNUsP44ZVXPQ+s7Vc10b9h2g6/eaChTve7omuCAni3Ug0Yhe+HlOBEjap4cpc0lzeFhHOqLJNJQgQ25VN17oy4zpLb4gzB7bs77pIygt1xO1Qh1yyMQC0w/cZs+9is0VQ4lITEaXP+q766/BXIOAuqszzdw1/Ca4dqs3lr5sajVSM4T7LQHo8bR565Rad4VY24KxLKLKEUzwQo86oM0C8KZATkL38UIWhzZlDzfh8twqX5gDpC7CzFRhdlNcxLUCMbLMUYUxdb3OTgeNw8VEN0OztxCJy5E2olrF6xbAxoNzLpi60lDQ==\",\"keyEncrypted\":\"jKqpkFxZPAv1kQGSvA2MbggEb962USnP6HBMrWBdVmydBUFNqrKJmoArqRG1VKuXEpkcfvzIatMqcw9Xr7RlZKmnJ+U4qkqyYwZV2wY85o3g6bqswIjF/z4TpaTrTJkaFs/5teWeG6X5bY4K+iu+as+ID8JvvGZlvGnn50+KDxw=\",\"timeStamp\":\"20220726015514\",\"interId\":\"orderPayDetail\"},\"signature\":\"13b95ffbe6be4bfa74d2de794e499be5\"}";
+
+        try {
+            String response = HttpUtils.doPost("http://117.141.148.233:8765/monolithic/uni/v1/sync", msg);
+            System.out.println(response);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private static void testEncrypt(){
+
+        //1. 本地,用对方的公钥加密
+        EncryptTools client = new EncryptTools("hd", f_remotePublicKeyBase6);
+
+        OrderPayDetailMessage detail = new OrderPayDetailMessage();
+        detail.setDate(DateUtil.format(new Date(), "yyyyMMdd"));
+        detail.setBatch(1);
+
+        //构造数据
+        OdsOrderPayDetailDTO order = new OdsOrderPayDetailDTO();
+        order.setSysId("hd");
+        order.setSysName("华东场站系统");
+        order.setYieldId("hd-a1");
+        order.setYieldName("华东A1园区");
+        order.setSyncType("insert");
+        order.setBatch("1");
+        order.setDwDt("20220725");
+        order.setDwTm("163206");
+        order.setUniqId("YRTFHFHFHFEWWR43645757");
+
+        List list = new ArrayList();
+        list.add(order);
+
+        detail.setList(list);
+        detail.setCount(list.size());
+
+        String encryptMessage = client.encryptMessage(detail);
+
+        //http传输
+
+        //2. 远端,用自己的私钥解密
+        EncryptTools server = new EncryptTools(f_remotePrivateKeyBase64);
+
+        MessageInter inter = server.decryptMessage(encryptMessage);
+
+
+    }
+
+}

+ 38 - 0
sp-server/src/main/java/com/pj/api/pushfee/api/PushFeeController.java

@@ -0,0 +1,38 @@
+package com.pj.api.pushfee.api;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.pj.project4sp.global.BusinessException;
+import com.pj.utils.cache.RedisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Auther: lzm
+ */
+@RequestMapping("PushFee")
+@RestController
+@Slf4j
+public class PushFeeController {
+
+    @RequestMapping(value = "changeStartTime")
+    public void changeStartTime(String startTime){
+        if(StrUtil.isEmpty(startTime)){
+            RedisUtil.del("pushFeeStartTime");
+            return;
+        }
+        DateUtil.parse(startTime, "yyyy-MM-dd HH:mm:ss");
+        RedisUtil.set("pushFeeStartTime", startTime);
+    }
+
+    @RequestMapping(value = "changeTimeSpan")
+    public void changeTimeSpan(String timeSpan){
+        if(StrUtil.isEmpty(timeSpan)){
+            RedisUtil.del("pushFeeTimeSpan");
+            return;
+        }
+        Integer.valueOf(timeSpan);
+        RedisUtil.set("pushFeeTimeSpan", timeSpan);
+    }
+}

+ 147 - 0
sp-server/src/main/java/com/pj/api/pushfee/task/FeeDetailSyncTask.java

@@ -0,0 +1,147 @@
+package com.pj.api.pushfee.task;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.pj.api.pushfee.tools.EncryptTools;
+import com.pj.api.pushfee.tools.message.api.OdsOrderPayDetailDTO;
+import com.pj.api.pushfee.tools.message.api.OrderPayDetailMessage;
+import com.pj.project.tb_fee_details.TbFeeDetails;
+import com.pj.project.tb_fee_details.TbFeeDetailsService;
+import com.pj.utils.cache.RedisUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @Auther: lzm
+ * @Date: 2022/07/25/9:11
+ */
+@Component
+@Slf4j
+public class FeeDetailSyncTask {
+    @Resource
+    TbFeeDetailsService tbFeeDetailsService;
+
+    //客户端公私钥
+    public static final String f_remotePublicKeyBase6 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCb5yK85EKqwiQU+z1jyjOng6ecssQpEjC6STbCuSWN6KHLkijBxdqrCumXhbIyOVx4lHK9Rg5EjzlQxoaXQTgJdItaGjLC+UTE+NNAnnaFLg0x4jajNpLo473zdZxTYQaT3q/aKnTeXuKHw11PPUe4hmmfxPcdt9yJ0Iqo/XxV3QIDAQAB";
+    public static final String f_remotePrivateKeyBase64 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJvnIrzkQqrCJBT7PWPKM6eDp5yyxCkSMLpJNsK5JY3oocuSKMHF2qsK6ZeFsjI5XHiUcr1GDkSPOVDGhpdBOAl0i1oaMsL5RMT400CedoUuDTHiNqM2kujjvfN1nFNhBpPer9oqdN5e4ofDXU89R7iGaZ/E9x233InQiqj9fFXdAgMBAAECgYASoeKgcaVYFCDM0yQIn5thy1XGYAUapX5mXSaqygbneWSQ2FR/qB5Ur9awEb30y682CAPYhB1jazyd30QpopVINvyhaWhgq1b/8KD92FqOg1eXxa7bTuTe8aMuKTB/ZJjEry0d5Mu3i6zYKtTSbnpnag5I3UE5awLDy7utYOoOHwJBAPtvz2ZBhtJvL3lsMgs7kGqrPqqI2LAX8J3oOCtE/6eQjQ0I5fBCybrwHp3baDrYul5KTL3kJvl4iWN/gHDi/nMCQQCeu3gzy0DVtM8M8bzFc/ZA753WRn4Z5axQa6lE7Tski8TUw4Bhbfan9E/C6l6Guo/+2hXPAE/RMcncClqeXXZvAkEAgf6FsO1x4fxABDvvB6Ws/ak5hfuoZCqMaWd1GtHah2yRsEqIbxZoq7CXc6/LDJmeiT9Ku+ZoTBSIm5uA8Vw6hwJALEbs872pmzMxYlH4Lzf2pAxzAbduK3kmhNRTRjfKfJpEUHksUYEkAZujuCI6NejKi/N3i+NxYFA8F5YHyw8VHwJAWoiYSYLSziHgDytoPKFvUp6EKLGDClhACJKc4LuaPNWICMxb5Dp88sY0NDYb4HzCyWIE5G4vbiF/K3kEEwCIVA==";
+
+    //服务端公私钥
+    public static final String f_localPublicKeyBase6 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCimSu5J8apt2YR/o9joOCNdFzO3rOHcdcqnSCm1Wt19VwskTVjkKHc/CXHUoskX5vMiMiv6xPnf/lDpMO6KnCrwlVQFtbPvmnkwyUs/haW8ggR865MqDcBpdMGnuV0YJ04UXxSrOX+eu+dl91Web4/ZiRKbObOa8WhFm/Ln2QKswIDAQAB";
+    public static final String f_localPrivateKeyBase6 = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKKZK7knxqm3ZhH+j2Og4I10XM7es4dx1yqdIKbVa3X1XCyRNWOQodz8JcdSiyRfm8yIyK/rE+d/+UOkw7oqcKvCVVAW1s++aeTDJSz+FpbyCBHzrkyoNwGl0wae5XRgnThRfFKs5f56752X3VZ5vj9mJEps5s5rxaEWb8ufZAqzAgMBAAECgYAmP/QaLXI9kIgxaXnfzQOmIx6GB7uh/DTKsIXy2TfbWunhDhPKJUb+jk5w0kkrOFaVSgQz5hAboG5J7GOi0sMINLb7H2WsOm3uGM/8HPZYsrNFnB8VUiD26LIZ6+HhPXfp/LN+k5eUnUlD6z/dZU1k6hJPOSFC3PyzfBWqaQMqGQJBAMVdQ9Uw+eC94qD1MSSEQZhqpfGE4vO7WrSACLFqyZrHvaIwZTjdUZRF1aMlJyT0afOkfSN/53QQEcejXMUrSBcCQQDS576SXkpdfrN2jmr9BAimi+6AP71GUgXL3O+2yRL2szLoU7GwtMREPBFw+ocnC4UN87NCYveJCzenQEt48JfFAkAqEIa0mYuoatAyng+rSMTyR0i3ASud5wCeF+vCZJAzfP7d4pKwW/tXLsspynFdXvp2A0jomAosooAnnJnZLDBhAkBzXoXm92Fip45wShPIeE5rHJzI1xUoxHGbRS50JKYVAY3VfQL0kM3ULa+0x7bq6uhL64WhyRVziAlXmlouvB2pAkEAuDvsjVhdo3uMGL7Tr+igPhajoWUTjPuAf+Od3SsqMTPFLBpbJM8ziXk39Me9S8wqgGwR3pnlC1Z6Rybgm+uy4g==";
+
+    private static final String URL = "http://117.141.148.233:8765/monolithic/uni/v1/sync";
+
+    //默认开始时间
+    private static final String START_TIME = "2022-04-29 00:00:00";
+    //默认同步时间间隔
+    private static final Integer TIME_SPAN = 86400000;
+    /**
+     * 5分钟执行一次
+     */
+    @Scheduled(fixedRate = 300000)
+    public void send() {
+        Date startTime;
+        Integer timeSpan;
+        //先从redis中获取startTime
+        if(StrUtil.isNotEmpty(RedisUtil.get("pushFeeStartTime"))){
+            startTime = DateUtil.parse(RedisUtil.get("pushFeeStartTime"), "yyyy-MM-dd HH:mm:ss");
+        }else{
+            startTime = DateUtil.parse(START_TIME, "yyyy-MM-dd HH:mm:ss");
+        }
+        //先从redis中获取timeSpan
+        if(StrUtil.isNotEmpty(RedisUtil.get("pushFeeTimeSpan"))){
+            timeSpan = Integer.valueOf(RedisUtil.get("pushFeeTimeSpan"));
+        }else{
+            timeSpan = TIME_SPAN;
+        }
+        Date finishTime = new Date();
+        Date offsetTime = DateUtil.offsetMillisecond(startTime, timeSpan);
+        //如果当前时间与开始时间的间隔小于设定间隔,则不执行下面代码,保证推送的时间间隔为设定间隔
+        if(DateUtil.compare(finishTime, offsetTime) > 0){
+            finishTime = offsetTime;
+        }else{
+            log.info("pushfee_warning: 当前时间与开始时间的间隔小于设定间隔,本次任务不进行推送,开始时间为" +
+                    DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss"));
+            return;
+        }
+        //构建数据
+        List<TbFeeDetails> fdList = getfeeDetails(startTime, finishTime);
+        List<OdsOrderPayDetailDTO> opdList = convert(fdList);
+
+        //1. 本地,用对方的公钥加密
+        EncryptTools client = new EncryptTools("hd", f_remotePublicKeyBase6);
+
+        OrderPayDetailMessage detail = new OrderPayDetailMessage();
+        detail.setDate(DateUtil.format(new Date(), "yyyyMMdd"));
+        detail.setBatch(1);
+        detail.setList(opdList);
+        detail.setCount(opdList.size());
+
+        String encryptMessage = client.encryptMessage(detail);
+        log.info("pushfee_encryptMessage: " + encryptMessage);
+
+        //推送数据
+        try {
+            String response = tools.http.HttpUtils.doPost(URL, encryptMessage);
+            log.info("pushfee_response: " + response);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        RedisUtil.set("pushFeeStartTime", DateUtil.format(finishTime, "yyyy-MM-dd HH:mm:ss"));
+        RedisUtil.set("pushFeeTimeSpan", timeSpan+"");
+        log.info("pushfee_warning: " + RedisUtil.get("pushFeeStartTime"));
+    }
+
+    private List<TbFeeDetails> getfeeDetails(Date startTime, Date finishTime) {
+        QueryWrapper<TbFeeDetails> qw = new QueryWrapper<>();
+        qw.ge("update_time", startTime).le("update_time", finishTime);
+        return tbFeeDetailsService.list(qw);
+    }
+
+    private List<OdsOrderPayDetailDTO> convert(List<TbFeeDetails> fdList) {
+        List<OdsOrderPayDetailDTO> opdList = new ArrayList<>();
+        for (TbFeeDetails fd : fdList) {
+            OdsOrderPayDetailDTO opd = new OdsOrderPayDetailDTO();
+            opd.setSysId("hd").setSysName("华东场站系统").setYieldId("hd-a1").setYieldName("华东A1园区")
+                .setSyncType("insert").setBatch("1")
+                .setDwDt("20220725").setDwTm("163206").setUniqId("YRTFHFHFHFEWWR43645757");
+
+            String bizNo = fd.getBusinessNo();
+            if(fd.getFeeType() == TbFeeDetails.fee.PARK_FEE.getCode()){
+                bizNo = fd.getBusinessCarNo();
+            }
+            opd.setBizNo(bizNo)
+                .setChargeItemId(fd.getFeeType()+"").setChargeItemName(TbFeeDetails.fee.getDesc(fd.getFeeType()))
+                .setBizTypeId(fd.getItemTypeId()).setBizTypeName(fd.getItemTypeName())
+                .setCarTypId(fd.getItemId()).setCarTypName(fd.getItemName())
+                .setCarNo(fd.getCarNo())
+                .setWeight(fd.getWeight() != null ? fd.getWeight()+"": "0")
+                .setNum(fd.getNum()+"")
+                .setPrice(fd.getUnitPrice().toString()).setTotalPrice(fd.getItemPrice().toString())
+                .setSettleStatusName("已结算")
+                .setTaxRate(fd.getTaxRate().toString()).setTaxPayment(fd.getTaxPrice().toString())
+                .setTaxAmount(fd.getItemPrice().toString()).setNoTaxAmount(fd.getNoTaxPrice().toString())
+                .setPaymentWayName("微信支付")
+                .setPayNo(fd.getTransactionId())
+                .setWorkNo(fd.getBusinessItemNo())
+                .setCustName(fd.getEntityName()).setPartnerName(fd.getPickCustomerName()).setAgentName(fd.getCustomerName())
+                .setInvoiceNo(fd.getInvoice())
+                .setCreateTime(DateUtil.format(fd.getCreateTime(), "yyyy-MM-dd HH:mm:ss")).setPayTime(fd.getPayTime())
+                .setRemarks(fd.getRemark())
+                .setBillClerkName(fd.getKaiDanPerson()).setStatAuditorName(fd.getJiChaPerson()).setDispatcherName(fd.getDiaoDuPerson());
+
+            opdList.add(opd);
+        }
+        return opdList;
+    }
+
+}

+ 185 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/EncryptTools.java

@@ -0,0 +1,185 @@
+package com.pj.api.pushfee.tools;
+
+import cn.hutool.core.codec.Base64;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.SecureUtil;
+import cn.hutool.crypto.asymmetric.KeyType;
+import cn.hutool.crypto.asymmetric.RSA;
+import cn.hutool.crypto.digest.DigestUtil;
+import cn.hutool.crypto.symmetric.AES;
+import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.pj.api.pushfee.tools.message.CuMessage;
+import com.pj.api.pushfee.tools.message.Header;
+import com.pj.api.pushfee.tools.message.Inter;
+import com.pj.api.pushfee.tools.message.MessageInter;
+
+public class EncryptTools {
+
+    private String sysId;
+
+    private String remotePublicKey;
+
+    private String localPrivateKey;
+
+    private RSA rsaInstance;
+
+    private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+
+    /**
+     * 构造加密工具
+     * @param sysId 系统Id,由统一计费系统分配
+     * @param remotePublicKey 对方的公钥
+     */
+    public EncryptTools(String sysId, String remotePublicKey) {
+        this.sysId = sysId;
+        this.remotePublicKey = remotePublicKey;
+        rsaInstance = SecureUtil.rsa(null, this.remotePublicKey);
+    }
+
+    /**
+     * 构造解密工具
+     * @param localPrivateKey 己方的私钥
+     */
+    public EncryptTools(String localPrivateKey) {
+        this.localPrivateKey = localPrivateKey;
+        rsaInstance = SecureUtil.rsa(this.localPrivateKey, null);
+    }
+
+    /**
+     * 生成RSA密钥对
+     */
+    public static void generateKeyPairs(){
+        RSA rsa = new RSA();
+        // 获取公钥
+        String pubKey = rsa.getPublicKeyBase64();
+        System.out.println("公钥:" + pubKey);
+        // 获取私钥
+        String priKey = rsa.getPrivateKeyBase64();
+        System.out.println("私钥:" + priKey);
+    }
+
+    /**
+     * md5签名
+     * @param text
+     * @return
+     */
+    private String md5(String text){
+        return DigestUtil.md5Hex(text);
+    }
+
+    /**
+     * RSA私钥解密
+     * @return
+     */
+    private String decryptStrByPrivateKey(String encrypt){
+        try {
+            return this.rsaInstance.decryptStr(encrypt, KeyType.PrivateKey);
+        } catch (Exception e) {
+            throw new RuntimeException("RSA私钥解密失败");
+        }
+    }
+
+    /**
+     * RSA公钥加密
+     * @param text
+     * @return
+     */
+    private String encryptByPublicKey(String text){
+        try {
+            return this.rsaInstance.encryptBase64(StrUtil.bytes(text,CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
+        } catch (Exception e) {
+            throw new RuntimeException("RSA公钥加密失败");
+        }
+    }
+
+    /**
+     * 生成随机秘钥
+     */
+    private String getRandomKey(){
+        return Base64.encode(SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded());
+    }
+
+    private String encodeByAES(String content, String randomKey){
+        try {
+            AES aes = SecureUtil.aes(Base64.decode(randomKey));
+            return aes.encryptBase64(content);
+        } catch (Exception e) {
+            throw new RuntimeException("AES加密报文失败");
+        }
+    }
+
+    private String decodeByAES(String sourceText, String randomKey){
+        try {
+            AES aes = SecureUtil.aes(Base64.decode(randomKey));
+            return aes.decryptStr(sourceText);
+        } catch (Exception e) {
+            throw new RuntimeException("AES解密报文失败");
+        }
+    }
+
+    private boolean verifySignature(CuMessage message){
+        String signature = message.getSignature();
+        return md5(gson.toJson(message.getHeader())).equals(signature);
+
+    }
+
+    /**
+     * 加密报文
+     */
+    public String encryptMessage(MessageInter payLoad){
+
+        //生成随机秘钥
+        String randomKey = getRandomKey();
+        //加密报文payLoad
+        String encrypted = encodeByAES(gson.toJson(payLoad), randomKey);
+        //加密随机秘钥
+        String keyEncrypted = encryptByPublicKey(randomKey);
+
+        Inter interAnnotation = payLoad.getClass().getAnnotation(Inter.class);
+        String interId = interAnnotation.name();
+
+        Header header = new Header(this.sysId, encrypted, keyEncrypted, interId);
+
+        //签名:md5提取摘要
+        String signature = md5(gson.toJson(header));
+
+        CuMessage cuMessage = new CuMessage(header, signature);
+
+        String msg = gson.toJson(cuMessage);
+
+        System.out.println("密文:" + msg);
+
+        return msg;
+
+    }
+
+    /**
+     * 解密报文
+     * @return
+     */
+    public MessageInter decryptMessage(String text){
+        CuMessage cuMessage = gson.fromJson(text, CuMessage.class);
+        return decryptMessage(cuMessage);
+    }
+
+    public MessageInter decryptMessage(CuMessage message){
+        //验签
+        if (!verifySignature(message)) {
+            throw new RuntimeException("验签失败");
+        }
+        //用公钥解密得到randomKey
+        String key = decryptStrByPrivateKey(message.getHeader().getKeyEncrypted());
+        //用randomKey解密报文
+        String originText = decodeByAES(message.getHeader().getEncrypted(), key);
+
+        MessageInter inter = gson.fromJson(originText, InterEnum.findClass(message.getHeader().getInterId()));
+
+        System.out.println("解密:" + originText);
+
+        return inter;
+    }
+
+}

+ 30 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/InterEnum.java

@@ -0,0 +1,30 @@
+package com.pj.api.pushfee.tools;
+
+import com.pj.api.pushfee.tools.message.api.OrderPayDetailMessage;
+import com.pj.api.pushfee.tools.message.MessageInter;
+
+public enum InterEnum {
+
+    ORDER_PAY_DETAIL(OrderPayDetailMessage.class, "orderPayDetail");
+
+    private Class<MessageInter> clazz;
+    private String interId;
+
+    InterEnum(Class clazz, String interId) {
+        this.clazz = clazz;
+        this.interId = interId;
+    }
+
+    public static Class<MessageInter> findClass(String interId){
+
+        int length = values().length;
+        for (int i = 0; i < length; i++) {
+            InterEnum interEnum = values()[i];
+            if (interEnum.interId.equals(interId)) {
+                return interEnum.clazz;
+            }
+        }
+        return null;
+    }
+
+}

+ 151 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/http/HttpUtils.java

@@ -0,0 +1,151 @@
+package tools.http;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.AuthSchemes;
+import org.apache.http.client.config.CookieSpecs;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.entity.BufferedHttpEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+public class HttpUtils {
+
+    private static String DEFAULT_ENCODING = "UTF-8";
+
+    private static HttpClient getClientNoSSL() {
+        try {
+            SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS);
+            ctx.init(null, new TrustManager[] { new MyTrustManager() }, null);
+            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
+            //  创建Registry
+            RequestConfig requestConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD_STRICT)
+                    .setExpectContinueEnabled(Boolean.TRUE).setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM,AuthSchemes.DIGEST))
+                    .setProxyPreferredAuthSchemes(Arrays.asList(AuthSchemes.BASIC)).build();
+            Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
+                    .register("http", PlainConnectionSocketFactory.INSTANCE)
+                    .register("https",socketFactory).build();
+            // 创建ConnectionManager,添加Connection配置信息
+            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
+            HttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(connectionManager)
+                    .setDefaultRequestConfig(requestConfig).build();
+            return closeableHttpClient;
+        } catch (KeyManagementException e) {
+            throw new RuntimeException(e);
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    /***
+         * 提交https或http Post请求
+         * @param url  请求url
+         * @param jsonEntity 请求体
+         * @throws IOException
+         */
+    public static String doPost(String url, String jsonEntity) throws IOException {
+
+        HttpClient httpClient = getClientNoSSL();
+
+        HttpResponse response = null;
+        try {
+            HttpPost post = new HttpPost(url);
+            post.setHeader("contentType", "application/json;charset=UTF-8");
+
+            StringEntity entity = new StringEntity(jsonEntity);
+            entity.setContentEncoding(DEFAULT_ENCODING);
+            entity.setContentType("application/json");
+
+            //提交json串
+            BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(entity);
+            post.setEntity(bufferedHttpEntity);
+            response =  httpClient.execute(post);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (response.getStatusLine().getStatusCode() == 200) {
+            return getResponseAsString(response);
+        }else {
+            return getResponseAsString(response);
+        }
+    }
+
+    public static String doGet(String url) throws IOException {
+
+        HttpClient httpClient = getClientNoSSL();
+
+        HttpResponse response = null;
+        try {
+            HttpGet get = new HttpGet(url);
+            get.setHeader("contentType", "application/json;charset=UTF-8");
+            response =  httpClient.execute(get);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        if (response.getStatusLine().getStatusCode() == 200) {
+            return getResponseAsString(response);
+        }else {
+            return getResponseAsString(response);
+        }
+    }
+
+    /**
+     * 将response响应消息转换为字符串
+     * @param response
+     * @return
+     * @throws IOException
+     */
+    public static String getResponseAsString(HttpResponse response) throws IOException {
+        String result = "";
+        HttpEntity resEntity = response.getEntity();
+        InputStreamReader reader = new InputStreamReader(resEntity.getContent());
+        char[] buff = new char[1024];
+        int length = 0;
+        while ((length = reader.read(buff)) != -1) {
+            result += new String(buff, 0, length);
+        }
+        return result;
+    }
+
+}
+
+/**
+ * 自定义重写自动接收所有证书
+ */
+class MyTrustManager implements X509TrustManager {
+
+    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+    }
+
+    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+
+}

+ 37 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/CuMessage.java

@@ -0,0 +1,37 @@
+package com.pj.api.pushfee.tools.message;
+
+public class CuMessage {
+
+    /**
+     * 报文头,加密后的数据均在此
+     */
+    private Header header;
+
+    /**
+     * 签名。由MD5(encrypted+ keyEncrypted+appSecret)得到。
+     * 注意签名必须是@Transient,否则序列化会出错
+     */
+    private String signature;
+
+    public CuMessage(Header header, String signature) {
+        this.header = header;
+        this.signature = signature;
+    }
+
+    public Header getHeader() {
+        return header;
+    }
+
+    public void setHeader(Header header) {
+        this.header = header;
+    }
+
+    public String getSignature() {
+        return signature;
+    }
+
+    public void setSignature(String signature) {
+        this.signature = signature;
+    }
+
+}

+ 89 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/Header.java

@@ -0,0 +1,89 @@
+package com.pj.api.pushfee.tools.message;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class Header {
+
+    /**
+     * 场站系统Id(由统计计费系统预分配)
+     */
+    public String sysId;
+
+    /**
+     * 密文。由秘钥randomKey,加密payload后得到
+     */
+    public String encrypted;
+
+    /**
+     * 加密秘钥。由公钥B加密randomKey得到
+     */
+    public String keyEncrypted;
+
+    /**
+     * 时间戳
+     */
+    public String timeStamp;
+
+    /**
+     * 接口Id
+     */
+    public String interId;
+
+    public Header(String sysId, String encrypted, String keyEncrypted, String interId) {
+        this.sysId = sysId;
+        this.encrypted = encrypted;
+        this.keyEncrypted = keyEncrypted;
+        this.timeStamp = generateTimeStamp();
+        this.interId = interId;
+    }
+
+    public Header() {
+        this.timeStamp = generateTimeStamp();
+    }
+
+    private String generateTimeStamp(){
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+        return format.format(new Date());
+    }
+
+    public String getEncrypted() {
+        return encrypted;
+    }
+
+    public void setEncrypted(String encrypted) {
+        this.encrypted = encrypted;
+    }
+
+    public String getKeyEncrypted() {
+        return keyEncrypted;
+    }
+
+    public void setKeyEncrypted(String keyEncrypted) {
+        this.keyEncrypted = keyEncrypted;
+    }
+
+    public String getTimeStamp() {
+        return timeStamp;
+    }
+
+    public void setTimeStamp(String timeStamp) {
+        this.timeStamp = timeStamp;
+    }
+
+    public String getInterId() {
+        return interId;
+    }
+
+    public void setInterId(String interId) {
+        this.interId = interId;
+    }
+
+    public String getSysId() {
+        return sysId;
+    }
+
+    public void setSysId(String sysId) {
+        this.sysId = sysId;
+    }
+}

+ 10 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/Inter.java

@@ -0,0 +1,10 @@
+package com.pj.api.pushfee.tools.message;
+
+import java.lang.annotation.*;
+
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface Inter {
+    String name();
+}

+ 12 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/MessageInter.java

@@ -0,0 +1,12 @@
+package com.pj.api.pushfee.tools.message;
+
+import java.io.Serializable;
+
+public interface MessageInter extends Serializable {
+
+    default String getInterId(){
+        Inter interAnnotation = this.getClass().getAnnotation(Inter.class);
+        return interAnnotation.name();
+    }
+
+}

+ 118 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/api/OdsOrderPayDetailDTO.java

@@ -0,0 +1,118 @@
+package com.pj.api.pushfee.tools.message.api;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+@Data
+@NoArgsConstructor
+@Accessors(chain = true)
+public class OdsOrderPayDetailDTO implements Serializable {
+
+    private String dwDt;
+
+    private String dwTm;
+    private String sysId;
+
+    private String sysName;
+
+    private String batch;
+
+    private String yieldId;
+
+    private String yieldName;
+
+    private String uniqId;
+
+    private String syncType;
+
+    private String bizNo;
+
+    private String chargeItemId;
+
+    private String chargeItemName;
+
+    private String bizTypeId;
+
+    private String bizTypeName;
+
+    private String carTypId;
+
+    private String carTypName;
+
+    private String carNo;
+
+    private String weight;
+
+    private String num;
+
+    private String price;
+
+    private String totalPrice;
+
+    private String settleStatusId;
+
+    private String settleStatusName;
+
+    private String checkStatusId;
+
+    private String checkStatusName;
+
+    private String taxRate;
+
+    private String taxPayment;
+
+    private String taxAmount;
+
+    private String noTaxAmount;
+
+    private String paymentWayId;
+
+    private String paymentWayName;
+
+    private String paymentCategoryId;
+
+    private String paymentCategoryName;
+
+    private String sysSerialNo;
+
+    private String payNo;
+
+    private String workNo;
+
+    private String custNo;
+
+    private String custName;
+
+    private String partnerId;
+
+    private String partnerName;
+
+    private String agentId;
+
+    private String agentName;
+
+    private String invoiceNo;
+
+    private String createTime;
+
+    private String payTime;
+
+    private String remarks;
+
+    private String billClerkId;
+
+    private String billClerkName;
+
+    private String statAuditorId;
+
+    private String statAuditorName;
+
+    private String dispatcherId;
+
+    private String dispatcherName;
+
+
+}

+ 23 - 0
sp-server/src/main/java/com/pj/api/pushfee/tools/message/api/OrderPayDetailMessage.java

@@ -0,0 +1,23 @@
+package com.pj.api.pushfee.tools.message.api;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import com.pj.api.pushfee.tools.message.Inter;
+import com.pj.api.pushfee.tools.message.MessageInter;
+
+import java.util.List;
+
+@Data
+@NoArgsConstructor
+@Inter(name = "orderPayDetail")
+public class OrderPayDetailMessage implements MessageInter {
+
+    String date;
+
+    int batch;
+
+    int count;
+
+    List<OdsOrderPayDetailDTO> list;
+
+}

+ 2 - 2
sp-server/src/main/resources/application-dev.yml

@@ -6,9 +6,9 @@ spring:
     # 数据源配置
     datasource:
         type: com.alibaba.druid.pool.DruidDataSource
-        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8
+        url: jdbc:mysql://127.0.0.1:3307/pco0726?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8
         username: root
-        password: 123456
+        password: 1234
         # 是否打开sql监控台  (生产环境请务必关闭此选项)
         druid:
             stat-view-servlet: