yonge 5 yıl önce
ebeveyn
işleme
93f83bfce1
34 değiştirilmiş dosya ile 3146 ekleme ve 9 silme
  1. BIN
      edu-thirdparty/libs/SADK-3.2.5.2.jar
  2. BIN
      edu-thirdparty/libs/adapay-java-sdk-1.0.2.jar
  3. BIN
      edu-thirdparty/libs/smUtil-1.0.jar
  4. BIN
      edu-thirdparty/libs/tech-sdk-2.1.20.jar
  5. BIN
      edu-thirdparty/libs/tgtext-3.2.14.jar
  6. BIN
      edu-thirdparty/libs/utils-3.0.6.jar
  7. 70 9
      edu-thirdparty/pom.xml
  8. 82 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/NotifyCallback.java
  9. 56 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/NotifyEvent.java
  10. 196 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/Pay.java
  11. 64 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/ESealPlugin.java
  12. 65 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/ESealPluginContext.java
  13. 260 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/provider/TsignPlugin.java
  14. 30 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/MessageSenderPlugin.java
  15. 108 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/MessageSenderPluginContext.java
  16. 238 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/JiguangPushPlugin.java
  17. 114 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/MOxintongSMSPlugin.java
  18. 124 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/ShiyuanSMSPlugin.java
  19. 89 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/YimeiSmsPlugin.java
  20. 63 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/GenerateNum.java
  21. 79 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/H5.java
  22. 60 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/Mp.java
  23. 81 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/NotifyMsg.java
  24. 145 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/UnionPay.java
  25. 15 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/UnionPayFeignService.java
  26. 296 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/CFCARAUtil.java
  27. 384 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/DateUtils.java
  28. 72 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/Intfc.java
  29. 57 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/Msg.java
  30. 81 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/NotifyMsg.java
  31. 68 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/RspMsg.java
  32. 79 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/RsqMsg.java
  33. 51 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/YqPayFeignService.java
  34. 119 0
      edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/YqPayUtil.java

BIN
edu-thirdparty/libs/SADK-3.2.5.2.jar


BIN
edu-thirdparty/libs/adapay-java-sdk-1.0.2.jar


BIN
edu-thirdparty/libs/smUtil-1.0.jar


BIN
edu-thirdparty/libs/tech-sdk-2.1.20.jar


BIN
edu-thirdparty/libs/tgtext-3.2.14.jar


BIN
edu-thirdparty/libs/utils-3.0.6.jar


+ 70 - 9
edu-thirdparty/pom.xml

@@ -7,25 +7,16 @@
     <artifactId>edu-saas</artifactId>
     <version>1.0</version>
   </parent>
-  <groupId>com.keao.edu</groupId>
   <artifactId>edu-thirdparty</artifactId>
-  <version>1.0</version>
   <name>edu-thirdparty</name>
   <url>http://maven.apache.org</url>
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
   </properties>
   <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>3.8.1</version>
-      <scope>test</scope>
-    </dependency>
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
-          <version>5.1.8.RELEASE</version>
           <scope>compile</scope>
       </dependency>
       <dependency>
@@ -37,5 +28,75 @@
       <groupId>com.keao.edu</groupId>
       <artifactId>edu-util</artifactId>
     </dependency>
+		
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>tech-sdk</artifactId>
+			<version>2.1.20</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/tech-sdk-2.1.20.jar</systemPath>
+		</dependency>
+		
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>smUtil</artifactId>
+			<version>1.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/smUtil-1.0.jar</systemPath>
+		</dependency>
+		
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>tgtext</artifactId>
+			<version>3.2.14</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/tgtext-3.2.14.jar</systemPath>
+		</dependency>
+		
+		<dependency>
+			<groupId>com.timevale</groupId>
+			<artifactId>utils</artifactId>
+			<version>3.0.6</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/utils-3.0.6.jar</systemPath>
+		</dependency>
+
+		<dependency>
+			<groupId>cfca.sadk</groupId>
+			<artifactId>cfca.sadk</artifactId>
+			<version>1.0.0</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/SADK-3.2.5.2.jar</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>adapay</groupId>
+			<artifactId>adapay-java-sdk</artifactId>
+			<version>1.0.2</version>
+			<scope>system</scope>
+			<systemPath>${project.basedir}/libs/adapay-java-sdk-1.0.2.jar
+			</systemPath>
+		</dependency>
+		<dependency>
+			<groupId>org.eclipse.paho</groupId>
+			<artifactId>org.eclipse.paho.client.mqttv3</artifactId>
+			<version>1.2.0</version>
+		</dependency>
+
+		<dependency>
+			<groupId>org.springframework.cloud</groupId>
+			<artifactId>spring-cloud-starter-openfeign</artifactId>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/io.github.openfeign.form/feign-form-spring -->
+		<dependency>
+			<groupId>io.github.openfeign.form</groupId>
+			<artifactId>feign-form-spring</artifactId>
+			<version>2.0.5</version>
+		</dependency>
+		<!-- https://mvnrepository.com/artifact/io.github.openfeign.form/feign-form-spring -->
+		<dependency>
+			<groupId>io.github.openfeign.form</groupId>
+			<artifactId>feign-form-spring</artifactId>
+			<version>2.0.5</version>
+		</dependency>
   </dependencies>
 </project>

+ 82 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/NotifyCallback.java

@@ -0,0 +1,82 @@
+package com.keao.edu.thirdparty.adapay;
+
+import com.alibaba.fastjson.JSON;
+import com.huifu.adapay.model.payment.Payment;
+import com.huifu.adapay.model.refund.Refund;
+import com.huifu.adapay.notify.INotifyCallback;
+/**
+ * @author jane.zhao
+ */
+public class NotifyCallback implements INotifyCallback {
+
+    /**
+     * 用户接收并处理支付成功的异步消息
+     * @param payment 成功的支付对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void paymentSuccessMessageArrived(Payment payment) throws Exception {
+        System.out.println("receive paymentSuccess msg=" + JSON.toJSONString(payment));
+
+    }
+
+    /**
+     * 用户接收并处理支付失败的异步消息
+     * @param payment 失败的支付对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void paymentFailedMessageArrived(Payment payment) throws Exception {
+        System.out.println("receive paymentFailed msg=" + JSON.toJSONString(payment));
+    }
+
+    /**
+     * 用户接收并处理关闭支付交易成功的异步消息
+     * @param payment 关闭成功的支付对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void paymentCloseSuccessMessageArrived(Payment payment) throws Exception {
+        System.out.println("receive paymentCloseSuccess msg=" + JSON.toJSONString(payment));
+    }
+
+    /**
+     * 用户接收并处理关闭支付交易失败的异步消息
+     * @param payment 关闭失败的支付对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void paymentCloseFailedMessageArrived(Payment payment) throws Exception {
+        System.out.println("receive paymentCloseFailed msg=" + JSON.toJSONString(payment));
+    }
+
+    /**
+     * 用户接收并处理退款成功的异步消息
+     * @param refund 成功的退款对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void refundSuccessMessageArrived(Refund refund) throws Exception {
+        System.out.println("receive refundSuccess msg=" + JSON.toJSONString(refund));
+    }
+
+    /**
+     * 用户接收并处理退款失败的异步消息
+     * @param refund 失败的退款对象
+     * @throws Exception 异常
+     */
+    @Override
+    public void refundFailedMessageArrived(Refund refund) throws Exception {
+        System.out.println("receive refundFailed msg=" + JSON.toJSONString(refund));
+    }
+
+    /**
+     * 用户接收并处理未知的异步消息
+     * @param msg 未知消息
+     * @throws Exception 异常
+     */
+    @Override
+    public void unknownMessageArrived(String msg) throws Exception {
+        System.out.println("receive unknown msg=" + msg);
+    }
+}

+ 56 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/NotifyEvent.java

@@ -0,0 +1,56 @@
+package com.keao.edu.thirdparty.adapay;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class NotifyEvent {
+    private String id;
+    private String type;
+    private String created_time;
+    private String prod_mode;
+    private String data;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getCreated_time() {
+        return created_time;
+    }
+
+    public void setCreated_time(String created_time) {
+        this.created_time = created_time;
+    }
+
+    public String getProd_mode() {
+        return prod_mode;
+    }
+
+    public void setProd_mode(String prod_mode) {
+        this.prod_mode = prod_mode;
+    }
+
+    public String getData() {
+        return data;
+    }
+
+    public void setData(String data) {
+        this.data = data;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+}

+ 196 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/adapay/Pay.java

@@ -0,0 +1,196 @@
+package com.keao.edu.thirdparty.adapay;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.huifu.adapay.AdaPay;
+import com.huifu.adapay.demo.BaseDemo;
+import com.huifu.adapay.demo.NotifyCallbackDemo;
+import com.huifu.adapay.exception.BaseAdaPayException;
+import com.huifu.adapay.model.DeviceInfo;
+import com.huifu.adapay.model.payment.*;
+import com.huifu.adapay.util.AdaPaySign;
+import org.aspectj.apache.bcel.classfile.Module;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * @author jane.zhao
+ */
+public class Pay {
+    private static final String appId = "app_7d87c043-aae3-4357-9b2c-269349a980d6";
+    private static final String wxAppId = "wxcf8e8b33a9477845";
+
+    /**
+     * 运行支付类接口
+     *
+     * @return paymentId
+     * @throws Exception 异常
+     */
+    public Pay() throws Exception {
+        //apiKey,商户联调用
+        String apiKey = "api_test_e640fa26-bbe6-458f-ac44-a71723ee2176";
+        //apiKey,真实交易用(live)
+        String apiKeyLive = "api_live_9c14f264-e390-41df-984d-df15a6952031";
+        //公钥
+        String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwN6xgd6Ad8v2hIIsQVnbt8a3JituR8o4Tc3B5WlcFR55bz4OMqrG/356Ur3cPbc2Fe8ArNd/0gZbC9q56Eb16JTkVNA/fye4SXznWxdyBPR7+guuJZHc/VW2fKH2lfZ2P3Tt0QkKZZoawYOGSMdIvO+WqK44updyax0ikK6JlNQIDAQAB";
+        //私钥
+        String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMQhsygJ2pp4nCiDAXiqnZm6AzKSVAh+C0BgGR6QaeXzt0TdSi9VR0OQ7Qqgm92NREB3ofobXvxxT+wImrDNk6R6lnHPMTuJ/bYpm+sx397rPboRAXpV3kalQmbZ3P7oxtEWOQch0zV5B1bgQnTvxcG3REAsdaUjGs9Xvg0iDS2tAgMBAAECgYAqGFmNdF/4234Yq9V7ApOE1Qmupv1mPTdI/9ckWjaAZkilfSFY+2KqO8bEiygo6xMFCyg2t/0xDVjr/gTFgbn4KRPmYucGG+FzTRLH0nVIqnliG5Ekla6a4gwh9syHfstbOpIvJR4DfldicZ5n7MmcrdEwSmMwXrdinFbIS/P1+QJBAOr6NpFtlxVSGzr6haH5FvBWkAsF7BM0CTAUx6UNHb+RCYYQJbk8g3DLp7/vyio5uiusgCc04gehNHX4laqIdl8CQQDVrckvnYy+NLz+K/RfXEJlqayb0WblrZ1upOdoFyUhu4xqK0BswOh61xjZeS+38R8bOpnYRbLf7eoqb7vGpZ9zAkEAobhdsA99yRW+WgQrzsNxry3Ua1HDHaBVpnrWwNjbHYpDxLn+TJPCXvI7XNU7DX63i/FoLhOucNPZGExjLYBH/wJATHNZQAgGiycjV20yicvgla8XasiJIDP119h4Uu21A1Su8G15J2/9vbWn1mddg1pp3rwgvxhw312oInbHoFMxsQJBAJlyDDu6x05MeZ2nMor8gIokxq2c3+cnm4GYWZgboNgq/BknbIbOMBMoe8dJFj+ji3YNTvi1MSTDdSDqJuN/qS0=";
+
+        //设置AdaPay全局参数,不同环境设置不同的apiKey/pubKey/privateKey
+        AdaPay.apiKey = apiKeyLive;
+        AdaPay.pubKey = pubKey;
+        AdaPay.privateKey = privateKey;
+        AdaPay.debug = true;
+
+        //启动 mqtt 异步监听
+        AdaPay.iNotifyCallback = new NotifyCallbackDemo();
+        AdaPay.startNotifyListener();
+    }
+
+    public static String executePaymentTest() throws Exception {
+        //test chargeId = "002112019080716223300005091372336111616";
+        Pay demo = new Pay();
+        //支付接口
+        String orderNo = "jsdk_payment_" + System.currentTimeMillis();
+        String payChannel = PayChannelEnum.ALIPAY_QR.getCode();
+        BigDecimal amount = new BigDecimal("0.01");
+        String orderSubject = "测试大雅订单";
+        String orderBody = "测试大雅订单";
+        Payment payment = demo.executePayment(amount, orderNo, payChannel, orderSubject, orderBody,null);
+        //支付查询接口
+        //demo.queryPayment(payment.getId());
+        //关单接口
+        //demo.closePayment(payment.getId());
+
+        return payment.getId();
+    }
+
+
+    public Map<String, Object> getPayMap(BigDecimal amount, String orderNo, String notifyUrl, String orderSubject, String orderBody) throws Exception {
+
+        Map<String, Object> paymentParams = new HashMap<>(10);
+        paymentParams.put("appId", appId);
+        paymentParams.put("amount", amount);
+        paymentParams.put("orderNo", orderNo);
+        paymentParams.put("notifyUrl", notifyUrl);
+        paymentParams.put("orderSubject", orderSubject);
+        paymentParams.put("orderBody", orderBody);
+        paymentParams.put("wxAppId", wxAppId);
+        String originalStr = JSONObject.toJSONString(paymentParams);
+
+        String sign = AdaPaySign.sign(originalStr, AdaPay.privateKey);
+        paymentParams.put("sign", sign);
+        paymentParams.put("host", "http://192.168.3.27:8000/api-student/studentOrder/executePayment");
+        paymentParams.remove(appId);
+        return paymentParams;
+    }
+
+    public boolean verifySign(BigDecimal amount, String orderNo, String notifyUrl, String orderSubject, String orderBody, String sign) throws Exception {
+        Map<String, Object> paymentParams = new HashMap<>(10);
+        paymentParams.put("appId", appId);
+        paymentParams.put("amount", amount);
+        paymentParams.put("orderNo", orderNo);
+        paymentParams.put("notifyUrl", notifyUrl);
+        paymentParams.put("orderSubject", orderSubject);
+        paymentParams.put("orderBody", orderBody);
+        String originalStr = JSONObject.toJSONString(paymentParams);
+        return AdaPaySign.verifySign(originalStr, sign, AdaPay.pubKey);
+    }
+
+    /**
+     * 执行一个支付交易
+     *
+     * @return 创建的支付对象
+     * @throws Exception 异常
+     */
+    public static Payment executePayment(BigDecimal amount, String orderNo, String payChannel, String orderSubject, String orderBody, String openid) throws Exception {
+        System.out.println("=======execute payment begin=======");
+        //创建支付对象的参数,全部参数请参考 https://docs.adapay.tech/api/04-trade.html#id3
+        Map<String, Object> paymentParams = new HashMap<>(10);
+        paymentParams.put("app_id", appId);
+        paymentParams.put("order_no", orderNo);
+        paymentParams.put("pay_channel", payChannel);
+        paymentParams.put("pay_amt", amount);
+        paymentParams.put("currency", CurrencyEnum.CNY.getCode());
+        paymentParams.put("goods_title", orderSubject);
+        paymentParams.put("goods_desc", orderBody);
+
+//        DeviceInfo deviceInfo = new DeviceInfo();
+//        deviceInfo.setDeviceType(DeviceTypeEnum.MOBILE.getCode());
+//        deviceInfo.setDeviceIp("127.0.0.1");
+//        paymentParams.put("device_info", deviceInfo);
+
+//        List<GoodsDetail> goodsDetailList = new ArrayList<>();
+//        GoodsDetail goodsDetail = new GoodsDetail();
+//        goodsDetail.setGoodsId("your goods id");
+//        goodsDetail.setGoodsName("your goods name");
+//        goodsDetail.setQuantity("1");
+//        goodsDetail.setPrice("100.00");
+//        goodsDetailList.add(goodsDetail);
+//
+//        PromotionDetail promotionDetail = new PromotionDetail();
+//        promotionDetail.setGoodsDetail(goodsDetailList);
+//        promotionDetail.setCostPrice("100.00");
+
+        if (openid != null && !openid.isEmpty()) {
+            PaymentExpend expend = new PaymentExpend();
+            expend.setWxAppId("wx751141096e75a4ee");
+            expend.setOpenId(openid);
+            expend.setIsRaw("0");
+            paymentParams.put("expend", expend);
+        }
+
+        //调用sdk方法,创建支付,得到支付对象
+        Payment payment = null;
+        try {
+            payment = Payment.create(paymentParams);
+        } catch (BaseAdaPayException e) {
+            e.printStackTrace();
+        }
+        System.out.println("payment result=" + JSON.toJSONString(payment));
+        return payment;
+    }
+
+    /**
+     * 关闭一个支付交易
+     *
+     * @param paymentId 要关闭的支付id
+     * @return 关闭的支付对象
+     * @throws Exception 异常
+     */
+    public Payment closePayment(String paymentId) throws Exception {
+        System.out.println("=======close payment begin=======");
+        //关闭支付对象的参数,全部参数请参考 https://docs.adapay.tech/api/04-trade.html#id11
+        //调用sdk方法,关闭支付,得到支付对象
+        Payment payment = null;
+        try {
+            payment = Payment.close(paymentId);
+        } catch (BaseAdaPayException e) {
+            e.printStackTrace();
+        }
+        System.out.println("close payment result=" + JSON.toJSONString(payment));
+        return payment;
+    }
+
+    /**
+     * 查询一个支付交易
+     *
+     * @param paymentId 要查询的支付id
+     * @return 查询的支付对象
+     * @throws Exception 异常
+     */
+    public Payment queryPayment(String paymentId) throws Exception {
+        System.out.println("=======query payment begin=======");
+        //查询支付对象的参数,全部参数请参考 https://docs.adapay.tech/api/04-trade.html#id7
+        //调用sdk方法,查询支付交易,得到支付对象
+        Payment payment = null;
+        try {
+            payment = Payment.query(paymentId);
+        } catch (BaseAdaPayException e) {
+            e.printStackTrace();
+        }
+        System.out.println("query payment result=" + JSON.toJSONString(payment));
+        return payment;
+    }
+}

+ 64 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/ESealPlugin.java

@@ -0,0 +1,64 @@
+package com.keao.edu.thirdparty.eseal;
+
+public interface ESealPlugin {
+
+	/**
+	 * 创建用户账户(个人)
+	 * @param realName 姓名
+	 * @param idcard 身份证号码
+	 * @param mobile 手机号码
+	 * @return 账户唯一标识
+	 */
+	public String createUserAccount(String realName, String idcard, String mobile);
+
+	/**
+	 * 创建用户账户(企业)
+	 * @param orgName  机构名称
+	 * @param organCode 统一社会信用代码
+	 * @return 账户唯一标识
+	 */
+	public String createOrganAccount(String orgName, String organCode);
+
+	/**
+	 * 创建个人印章
+	 * @param accountId 账户唯一标识
+	 * @return 电子印章数据
+	 */
+	public String createUserSeal(String accountId);
+
+	/**
+	 * 创建企业印章
+	 * @param accountId 账户唯一标识
+	 * @param hText 生成印章中的横向文内容
+	 * @param qText 生成印章中的下弦文内容
+	 * @return 电子印章数据
+	 */
+	public String createOrganSeal(String accountId, String hText, String qText);
+
+	/**
+	 * 平台自身PDF摘要签署(印章标识)
+	 * @param srcPdfPath 源文件
+	 * @param destPdfPath 签名后的目标文件
+	 * @return
+	 */
+	public boolean platformSign(String srcPdfPath, String destPdfPath);
+
+	/**
+	 * 企业PDF摘要签署(印章图片)
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 源文件
+	 * @param destPdfPath 签名后的目标文件
+	 * @return
+	 */
+	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath);
+
+	/**
+	 * 用户签名
+	 * @param accountId 账户唯一标识
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 平台签名后的源文件
+	 * @param destPdfPath 平台、用户都签名后的文件地址
+	 * @return
+	 */
+	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath);
+}

+ 65 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/ESealPluginContext.java

@@ -0,0 +1,65 @@
+package com.keao.edu.thirdparty.eseal;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import com.keao.edu.thirdparty.eseal.provider.TsignPlugin;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+
+@Component
+public class ESealPluginContext implements ApplicationContextAware, InitializingBean {
+	
+	@Value("${thirdparty.eSealPluginName:Tsign}")
+	private String eSealPluginName;
+	
+	private ApplicationContext applicationContext;
+
+	private final Map<String, String> mapper = new HashMap<String, String>() {
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = -9071481806931421021L;
+
+		{
+			put(TsignPlugin.getName(), StringUtils.uncapitalize(TsignPlugin.class.getSimpleName()));
+		}
+	};
+
+	private ESealPlugin eSealPlugin;
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		if (StringUtils.isBlank(eSealPluginName)) {
+			throw new ThirdpartyException("存储插件变量thirdparty.storagePlugName不能为空");
+		}
+
+		eSealPlugin = getStoragePlugin(eSealPluginName);
+
+		if (eSealPlugin == null) {
+			throw new ThirdpartyException("电子签章插件{}不存在", eSealPluginName);
+		}
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	private ESealPlugin getStoragePlugin(String vendors) {
+		String beanId = mapper.get(vendors);
+
+		if (StringUtils.isBlank(beanId)) {
+			throw new ThirdpartyException("电子签章提供商不存在");
+		}
+
+		return applicationContext.getBean(beanId, ESealPlugin.class);
+	}
+}

+ 260 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/eseal/provider/TsignPlugin.java

@@ -0,0 +1,260 @@
+package com.keao.edu.thirdparty.eseal.provider;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.keao.edu.thirdparty.eseal.ESealPlugin;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.timevale.esign.sdk.tech.bean.AccountProfile;
+import com.timevale.esign.sdk.tech.bean.OrganizeBean;
+import com.timevale.esign.sdk.tech.bean.PersonBean;
+import com.timevale.esign.sdk.tech.bean.PosBean;
+import com.timevale.esign.sdk.tech.bean.SignPDFFileBean;
+import com.timevale.esign.sdk.tech.bean.result.AddAccountResult;
+import com.timevale.esign.sdk.tech.bean.result.AddSealResult;
+import com.timevale.esign.sdk.tech.bean.result.FileDigestSignResult;
+import com.timevale.esign.sdk.tech.bean.result.GetAccountProfileResult;
+import com.timevale.esign.sdk.tech.bean.result.Result;
+import com.timevale.esign.sdk.tech.bean.seal.OrganizeTemplateType;
+import com.timevale.esign.sdk.tech.bean.seal.PersonTemplateType;
+import com.timevale.esign.sdk.tech.bean.seal.SealColor;
+import com.timevale.esign.sdk.tech.impl.constants.LegalAreaType;
+import com.timevale.esign.sdk.tech.impl.constants.LicenseQueryType;
+import com.timevale.esign.sdk.tech.impl.constants.OrganRegType;
+import com.timevale.esign.sdk.tech.impl.constants.SignType;
+import com.timevale.esign.sdk.tech.service.AccountService;
+import com.timevale.esign.sdk.tech.service.SealService;
+import com.timevale.esign.sdk.tech.service.SelfSignService;
+import com.timevale.esign.sdk.tech.service.UserSignService;
+import com.timevale.esign.sdk.tech.v3.client.ServiceClient;
+import com.timevale.esign.sdk.tech.v3.client.ServiceClientManager;
+import com.timevale.tech.sdk.bean.ProjectConfig;
+
+@Service
+public class TsignPlugin implements ESealPlugin, InitializingBean, DisposableBean {
+
+	@Value("${eseal.tsign.projectid:4438776254}")
+	public String projectId; // = "1111563517";
+
+	@Value("${eseal.tsign.projectSecret:a94cf63d6361084d232f345d71321691}")
+	public String projectSecret; // = "95439b0863c241c63a861b87d1e647b7";
+
+	@Value("${eseal.tsign.apisUrl:http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2}")
+	public String apisUrl; // = "http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2";
+
+	private ServiceClient serviceClient;
+
+	public static String getName() {
+		return "Tsign";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		ProjectConfig projectconfig = new ProjectConfig();
+		projectconfig.setProjectId(projectId);
+		projectconfig.setProjectSecret(projectSecret);
+		projectconfig.setItsmApiUrl(apisUrl);
+		Result result = ServiceClientManager.registClient(projectconfig, null, null);
+		if (result.getErrCode() != 0) {
+			throw new ThirdpartyException("e签宝客户端注册失败:{}", result.getMsg());
+		}
+
+		serviceClient = ServiceClientManager.get(projectId);
+		if (serviceClient == null) {
+			throw new ThirdpartyException("获取e签宝客户端失败");
+		}
+	}
+
+	@Override
+	public void destroy() throws Exception {
+		ServiceClientManager.shutdown(projectId);
+	}
+
+	/**
+	 * 创建用户账户(个人)
+	 * @param realName 姓名
+	 * @param idcard 身份证号码
+	 * @param mobile 手机号码
+	 * @return e签宝账户唯一标识
+	 */
+	public String createUserAccount(String realName, String idcard, String mobile) {
+		PersonBean personbean = new PersonBean();
+		personbean.setName(realName);
+		personbean.setIdNo(idcard);
+		personbean.setMobile(mobile);
+		personbean.setPersonArea(LegalAreaType.MAINLAND);
+		// personbean.setPersonArea(4);
+		AccountService service = serviceClient.accountService();
+		AddAccountResult result = service.addAccount(personbean);
+		if (result.getErrCode() == 0) {
+			return result.getAccountId();
+		} else if (result.getErrCode() == 1500012) {
+			return queryAccountIdByIdNo(idcard);
+		}
+		throw new ThirdpartyException(result.getMsg());
+	}
+
+	/**
+	 * 创建用户账户(企业)
+	 * @param orgName  机构名称
+	 * @param organCode 统一社会信用代码
+	 * @return e签宝账户唯一标识
+	 */
+	public String createOrganAccount(String orgName, String organCode) {
+		OrganizeBean organizeBean = new OrganizeBean();
+		organizeBean.setName(orgName);
+		organizeBean.setOrganCode(organCode);
+		organizeBean.setRegType(OrganRegType.MERGE);
+		organizeBean.setUserType(0);
+
+		AccountService service = serviceClient.accountService();
+		AddAccountResult result = service.addAccount(organizeBean);
+		if (result.getErrCode() == 0) {
+			return result.getAccountId();
+		}
+		throw new ThirdpartyException("创建企业账户接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+	}
+
+	/**
+	 * 创建印章
+	 * @param accountId e签宝账户唯一标识
+	 * @return 电子印章数据
+	 */
+	public String createUserSeal(String accountId) {
+		// 生成模板印章的颜色
+		SealColor color = SealColor.RED;
+		SealService service = serviceClient.sealService();
+		AddSealResult result = service.addTemplateSeal(accountId, PersonTemplateType.RECTANGLE, color);
+		if (0 == result.getErrCode()) {
+			return result.getSealData();
+		}
+		throw new ThirdpartyException("个人模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+	}
+
+	@Override
+	public String createOrganSeal(String accountId, String hText, String qText) {
+		// 生成模板印章的颜色
+		SealColor color = SealColor.RED;
+		SealService service = serviceClient.sealService();
+		AddSealResult result = service.addTemplateSeal(accountId, OrganizeTemplateType.STAR, color, hText, qText);
+		if (0 == result.getErrCode()) {
+			return result.getSealData();
+		}
+		throw new ThirdpartyException("企业模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
+	}
+
+	/**
+	 * 平台自身PDF摘要签署(印章标识)
+	 * @param srcPdfPath 源文件
+	 * @param destPdfPath 签名后的目标文件
+	 * @return
+	 */
+	public boolean platformSign(String srcPdfPath, String destPdfPath) {
+		PosBean posBean = new PosBean();
+		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+		SignType signType = SignType.Key;
+		// 接口调用方(平台方)的印章,请在www.tsign.cn官网中设置默认印章其sealId值为0
+		int sealId = 0;
+		// 设置接口调用方(平台方)签章位置信息
+		posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+		posBean.setKey("甲方签章");
+		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+		posBean.setPosX(100);
+		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+		posBean.setPosY(0);
+		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+		posBean.setWidth(100);
+		SignPDFFileBean PDFbean = new SignPDFFileBean();
+		PDFbean.setSrcPdfFile(srcPdfPath);
+		PDFbean.setDstPdfFile(destPdfPath);
+
+		SelfSignService service = serviceClient.selfSignService();
+		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealId, signType);
+		if (0 != result.getErrCode()) {
+			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+		}
+		return true;
+	}
+
+	/**
+	 * 企业PDF摘要签署(印章图片)
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 源文件
+	 * @param destPdfPath 签名后的目标文件
+	 * @return
+	 */
+	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
+		PosBean posBean = new PosBean();
+		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+		SignType signType = SignType.Key;
+		// 设置接口调用方(平台方)签章位置信息
+		posBean.setPosPage("1");// 签署页码,若为多页签章,支持页码格式“1-3,5,8“,若为坐标定位时,不可空
+		posBean.setKey("甲方签章");
+		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
+		posBean.setPosX(100);
+		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
+		posBean.setPosY(0);
+		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
+		posBean.setWidth(100);
+		SignPDFFileBean PDFbean = new SignPDFFileBean();
+		PDFbean.setSrcPdfFile(srcPdfPath);
+		PDFbean.setDstPdfFile(destPdfPath);
+
+		SelfSignService service = serviceClient.selfSignService();
+		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealData, signType);
+		if (0 != result.getErrCode()) {
+			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败!Code=" + result.getErrCode() + "MSG=" + result.getMsg());
+		}
+		return true;
+	}
+
+	/**
+	 * 用户签名
+	 * @param accountId e签宝账户唯一标识
+	 * @param sealData 电子印章数据
+	 * @param srcPdfPath 平台签名后的源文件
+	 * @param destPdfPath 平台、用户都签名后的文件地址
+	 * @return
+	 */
+	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {
+
+		SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
+		// C:test_signed.pdf为平台自身签署后路径
+		signPDFStreamBean.setSrcPdfFile(srcPdfPath);
+		signPDFStreamBean.setDstPdfFile(destPdfPath);
+		PosBean posBean = new PosBean();
+		posBean.setPosPage("1");
+		posBean.setPosType(1);
+		posBean.setWidth(80);
+		posBean.setKey("乙方签章");
+		posBean.setPosX(100);
+		posBean.setPosY(0);
+
+		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
+		SignType signtype = SignType.Key;
+		UserSignService service = serviceClient.userSignService();
+		FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
+		if (result.getErrCode() == 0) {
+			return true;
+		}
+		throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
+	}
+
+	private String queryAccountIdByIdNo(String idcardNo) {
+
+		AccountService service = serviceClient.accountService();
+
+		GetAccountProfileResult result = service.getAccountInfoByIdNo(idcardNo, LicenseQueryType.MAINLAND);
+
+		if (result != null) {
+			AccountProfile accountProfile = result.getAccountInfo();
+			if (accountProfile != null) {
+				return accountProfile.getAccountUid();
+			}
+		}
+
+		return null;
+	}
+}

+ 30 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/MessageSenderPlugin.java

@@ -0,0 +1,30 @@
+package com.keao.edu.thirdparty.message;
+
+import java.io.IOException;
+
+public interface MessageSenderPlugin {
+	
+	/**
+	 * 发送消息至目的地
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receiver 收件人
+	 * @param url 链接地址
+	 * @param jpushType 极光应用类型
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean send(String subject, String content, String receiver, String url, String jpushType) throws Exception;
+
+	/**
+	 * 批量发送消息至目的地
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receivers 收件人列表
+	 * @param url 链接地址
+	 * @param jpushType 极光应用类型
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType) throws Exception;
+}

+ 108 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/MessageSenderPluginContext.java

@@ -0,0 +1,108 @@
+package com.keao.edu.thirdparty.message;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.keao.edu.thirdparty.message.provider.JiguangPushPlugin;
+import com.keao.edu.thirdparty.message.provider.MOxintongSMSPlugin;
+import com.keao.edu.thirdparty.message.provider.ShiyuanSMSPlugin;
+import com.keao.edu.thirdparty.message.provider.YimeiSmsPlugin;
+
+@Component
+public class MessageSenderPluginContext implements ApplicationContextAware {
+
+	public enum MessageSender {
+
+		JIGUANG("PUSH"), MOXINGTONG("SMS"), SHIYUAN("SMS"), YIMEI("SMS");
+
+		/**
+		 * 发送模式(SMS,PUSH,EMAIL)
+		 */
+		private String sendMode;
+
+		private MessageSender(String sendMode) {
+			this.sendMode = sendMode;
+		}
+
+		public String getSendMode() {
+			return sendMode;
+		}
+	}
+
+	private MessageSenderPlugin messageSenderPlugin;
+
+	private ApplicationContext applicationContext;
+
+	private final Map<String, String> mapper = new HashMap<String, String>() {
+
+		/**
+		 * 
+		 */
+		private static final long serialVersionUID = -3964872523891264522L;
+
+		{
+			put(StringUtils.lowerCase(JiguangPushPlugin.getName()), StringUtils.uncapitalize(JiguangPushPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(MOxintongSMSPlugin.getName()), StringUtils.uncapitalize(MOxintongSMSPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(ShiyuanSMSPlugin.getName()), StringUtils.uncapitalize(ShiyuanSMSPlugin.class.getSimpleName()));
+			put(StringUtils.lowerCase(YimeiSmsPlugin.getName()), StringUtils.uncapitalize(YimeiSmsPlugin.class.getSimpleName()));
+		}
+	};
+
+	/**
+	 * 发送消息至目的地
+	 * @param messageSender 消息发送方
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receiver 收件人
+	 * @param url 链接地址
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean send(MessageSender messageSender, String subject, String content, String receiver, String url, String jpushType) throws Exception {
+
+		messageSenderPlugin = getMessageSenderPlugin(messageSender);
+
+		return messageSenderPlugin.send(subject, content, receiver, url, jpushType);
+	}
+
+	/**
+	 * 批量发送消息至目的地
+	 * @param messageSender 消息发送方
+	 * @param subject 消息主题
+	 * @param content 消息内容
+	 * @param receivers 收件人列表
+	 * @param url 链接地址
+	 * @return 是否发送成功
+	 * @throws IOException
+	 */
+	public boolean batchSend(MessageSender messageSender, String subject, String content, String[] receivers, String url, String jpushType) throws Exception {
+
+		messageSenderPlugin = getMessageSenderPlugin(messageSender);
+
+		return messageSenderPlugin.batchSend(subject, content, receivers, url, jpushType);
+	}
+
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		this.applicationContext = applicationContext;
+	}
+
+	private MessageSenderPlugin getMessageSenderPlugin(MessageSender messageSender) {
+		String beanId = mapper.get(StringUtils.lowerCase(messageSender.name()));
+
+		if (StringUtils.isBlank(beanId)) {
+			throw new ThirdpartyException("消息提供方:{}不存在", beanId);
+		}
+
+		return applicationContext.getBean(beanId, MessageSenderPlugin.class);
+	}
+
+}

+ 238 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/JiguangPushPlugin.java

@@ -0,0 +1,238 @@
+package com.keao.edu.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.stream.Collectors;
+
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.keao.edu.thirdparty.message.MessageSenderPlugin;
+import com.keao.edu.util.http.HttpUtil;
+
+/**
+ * 极光推送
+ */
+@Service
+public class JiguangPushPlugin implements MessageSenderPlugin, InitializingBean {
+
+	@Value("${push.jiguang.appKey.student}")
+	private String studentAppKey;
+	@Value("${push.jiguang.masterSecret.student}")
+	private String studentMasterSecret;
+
+	@Value("${push.jiguang.appKey.teacher}")
+	private String teacherAppKey;
+	@Value("${push.jiguang.masterSecret.teacher}")
+	private String teacherMasterSecret;
+
+	@Value("${push.jiguang.appKey.system}")
+	private String systemAppKey;
+	@Value("${push.jiguang.masterSecret.system}")
+	private String systemMasterSecret;
+
+	@Value("${push.jiguang.apns_production:false}")
+	private boolean apns_production = true; // 推送环境 True 表示推送生产环境,False 表示要推送开发环境
+
+	@Value("${push.jiguang.time_to_live:86400}")
+	private int time_to_live = 86400; // 离线保留时长 秒为单位 默认1天 最大10天
+
+	@Value("${push.jiguang.reqURL:https://api.jpush.cn/v3/push}")
+	private String reqURL = "https://api.jpush.cn/v3/push";// 请求极光地址
+
+	public static String getName() {
+		return "jiguang";
+	}
+
+	/**
+	 * 组装推送Json串
+	 *
+	 * @param alias 别名推送
+	 * @param alert 消息
+	 * @param content 消息内容
+	 * @return json对象
+	 */
+	private JSONObject generateJson(String[] alias, String alert, String content, String url) {
+		JSONObject json = new JSONObject();
+		JSONArray platform = new JSONArray();// 平台
+		platform.add("android");
+		platform.add("ios");
+
+		JSONObject audience = new JSONObject();// 推送目标
+		JSONArray aliasJsonArr = new JSONArray();
+		for (String alia : alias) {
+			aliasJsonArr.add(alia);
+		}
+		audience.put("alias", aliasJsonArr);
+
+		JSONObject notification = new JSONObject();// 通知内容
+		JSONObject android = new JSONObject();// android通知内容
+		android.put("alert", alert);
+		android.put("builder_id", 1);
+		JSONObject android_extras = new JSONObject();// android额外参数
+		android_extras.put("type", "infomation");
+		android_extras.put("url", url);
+		android_extras.put("memo", url);
+		android.put("extras", android_extras);
+
+		JSONObject ios = new JSONObject();// ios通知内容
+		ios.put("alert", alert);
+		ios.put("sound", "default");
+		ios.put("badge", "+1");
+		JSONObject ios_extras = new JSONObject();// ios额外参数
+		ios_extras.put("type", "infomation");
+		ios_extras.put("url", url);
+		ios_extras.put("memo", url);
+		ios.put("extras", ios_extras);
+		notification.put("android", android);
+		notification.put("ios", ios);
+
+		JSONObject message = new JSONObject();// 通知消息内容
+		message.put("title", alert);
+		message.put("msg_content", content);
+		message.put("content_type", "text");
+
+		JSONObject options = new JSONObject();// 设置参数
+		options.put("time_to_live", this.time_to_live);
+		options.put("apns_production", this.apns_production);
+
+		json.put("platform", platform);
+		json.put("audience", audience);
+		json.put("notification", notification);
+		json.put("options", options);
+		json.put("message", message);
+		return json;
+
+	}
+
+	/**
+	 * 调用极光api
+	 * @param alias 推送对象别名
+	 * @param alert 推送消息
+	 * @param content 推送内容
+	 */
+	private String push(String[] alias, String alert, String content, String url,String type) {
+		String base64_auth_string = "";
+		switch (type){
+			case "STUDENT":
+				base64_auth_string = encryptBASE64(this.studentAppKey + ":" + this.studentMasterSecret);
+				break;
+			case "TEACHER":
+				base64_auth_string = encryptBASE64(this.teacherAppKey + ":" + this.teacherMasterSecret);
+				break;
+			default:
+				base64_auth_string = encryptBASE64(this.systemAppKey + ":" + this.systemMasterSecret);
+				break;
+		}
+		String authorization = "Basic " + base64_auth_string;
+		return sendPostRequest(generateJson(alias, alert, content, url).toString(), authorization);
+	}
+
+	/**
+	 * 发送Post请求(json格式)
+	 *
+	 * @param data //封装的json串
+	 * @param authorization 验签
+	 * @return result 返回一个json字符串
+	 */
+	private String sendPostRequest(String data, String authorization) {
+		String result = "";
+		HashMap<String, String> reqHeader = new HashMap<>();
+		reqHeader.put("Authorization", authorization.trim());
+		try {
+			result = HttpUtil.postForHttps(this.reqURL, data, reqHeader);
+		} catch (Exception e) {
+			throw new ThirdpartyException("HttpUtil Connection Exception", e);
+		}
+		return result;
+	}
+
+	/**
+	 *     * BASE64加密工具
+	 */
+	private String encryptBASE64(String str) {
+		byte[] key = str.getBytes();
+		String strs = Base64.encodeBase64String(key);
+		return strs;
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		/*if (StringUtils.isBlank(appKey)) {
+			throw new RuntimeException("Init parameter [appKey] can not blank");
+		}
+		if (StringUtils.isBlank(masterSecret)) {
+			throw new RuntimeException("Init parameter [masterSecret] can not blank");
+		}
+		if (StringUtils.isBlank(reqURL)) {
+			throw new RuntimeException("Init parameter [reqURL] can not blank");
+		}*/
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String type) throws IOException {
+		String[] alias = { receiver };
+		String result = this.push(alias, subject, content, url,type);
+		JSONObject json = JSONObject.parseObject(result);
+		if (json.containsKey("error")) {
+			JSONObject jsonObject = json.getJSONObject("error");
+			throw new ThirdpartyException(jsonObject.get("message").toString());
+		}
+		return true;
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String type) throws IOException {
+		String result = this.push(receivers, subject, content, url,type);
+		JSONObject json = JSONObject.parseObject(result);
+		if (json.containsKey("error")) {
+			JSONObject jsonObject = json.getJSONObject("error");
+			throw new ThirdpartyException(jsonObject.get("message").toString()+"["+Arrays.stream(receivers).collect(Collectors.joining(","))+"]");
+		}
+		return true;
+	}
+
+	public void setStudentAppKey(String studentAppKey) {
+		this.studentAppKey = studentAppKey;
+	}
+
+	public void setStudentMasterSecret(String studentMasterSecret) {
+		this.studentMasterSecret = studentMasterSecret;
+	}
+
+	public void setTeacherAppKey(String teacherAppKey) {
+		this.teacherAppKey = teacherAppKey;
+	}
+
+	public void setTeacherMasterSecret(String teacherMasterSecret) {
+		this.teacherMasterSecret = teacherMasterSecret;
+	}
+
+	public void setSystemAppKey(String systemAppKey) {
+		this.systemAppKey = systemAppKey;
+	}
+
+	public void setSystemMasterSecret(String systemMasterSecret) {
+		this.systemMasterSecret = systemMasterSecret;
+	}
+
+	public void setApns_production(boolean apns_production) {
+		this.apns_production = apns_production;
+	}
+
+	public void setTime_to_live(int time_to_live) {
+		this.time_to_live = time_to_live;
+	}
+
+	public void setReqURL(String reqURL) {
+		this.reqURL = reqURL;
+	}
+
+}

+ 114 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/MOxintongSMSPlugin.java

@@ -0,0 +1,114 @@
+package com.keao.edu.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.keao.edu.thirdparty.message.MessageSenderPlugin;
+import com.keao.edu.util.http.HttpUtil;
+
+/**
+ * MO信通短信验证码接口
+ */
+@Service
+public class MOxintongSMSPlugin implements MessageSenderPlugin, InitializingBean {
+
+	private static ObjectMapper MAPPER = new ObjectMapper();
+
+	@Value("${Moxintong.username:1}")
+	private String username;
+	
+	@Value("${Moxintong.pwd:1}")
+	private String pwd;
+	
+	@Value("${Moxintong.reqUrl:1}")
+	private String reqUrl;
+
+	public static String getName() {
+		return "moxintong";
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url, String jpushType) throws IOException {
+		Map<String, Object> reqParams = new HashMap<String, Object>();
+		reqParams.put("username", username);
+		reqParams.put("pwd", pwd);
+		reqParams.put("mobile", receiver);
+		reqParams.put("content", "【袋鼠卡】" + content);
+
+		String result = "";
+		try {
+			result = HttpUtil.postForHttps(reqUrl, reqParams);
+		} catch (Exception e) {
+			throw new ThirdpartyException("短信发送失败!", e);
+		}
+		HashMap jsonObject = MAPPER.readValue(result, HashMap.class);
+		if (jsonObject.get("code").toString().equals("0")) {
+			return true;
+		} else {
+			throw new ThirdpartyException(jsonObject.get("msg").toString());
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url, String jpushType) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder();
+		for (int i = 0; i < receivers.length - 1; i++) {
+			stringBuilder.append(receivers[i]).append(",");
+		}
+		stringBuilder.append(receivers[receivers.length - 1]);
+
+		Map<String, Object> reqParams = new HashMap<String, Object>();
+		reqParams.put("username", username);
+		reqParams.put("pwd", pwd);
+		reqParams.put("mobile", stringBuilder.toString());
+		reqParams.put("content", "【兰鲸分期】" + content);
+
+		String result = "";
+		try {
+			result = HttpUtil.postForHttps(reqUrl, reqParams);
+		} catch (Exception e) {
+			throw new ThirdpartyException("短信发送失败!", e);
+		}
+		HashMap jsonObject = MAPPER.readValue(result, HashMap.class);
+		if (jsonObject.get("code").toString().equals("0")) {
+			return true;
+		} else {
+			throw new ThirdpartyException(jsonObject.get("msg").toString());
+		}
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		if (StringUtils.isBlank(reqUrl)) {
+			throw new RuntimeException("Init parameter [reqUrl] can not blank");
+		}
+		if (StringUtils.isBlank(username)) {
+			throw new RuntimeException("Init parameter [username] can not blank");
+		}
+		if (StringUtils.isBlank(pwd)) {
+			throw new RuntimeException("Init parameter [pwd] can not blank");
+		}
+	}
+
+	public void setUsername(String username) {
+		this.username = username;
+	}
+
+	public void setPwd(String pwd) {
+		this.pwd = pwd;
+	}
+
+	public void setReqUrl(String reqUrl) {
+		this.reqUrl = reqUrl;
+	}
+
+}

+ 124 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/ShiyuanSMSPlugin.java

@@ -0,0 +1,124 @@
+package com.keao.edu.thirdparty.message.provider;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.keao.edu.thirdparty.message.MessageSenderPlugin;
+import com.keao.edu.util.http.HttpUtil;
+
+/**
+ * 示远短信验证码接口
+ */
+@Service
+public class ShiyuanSMSPlugin implements MessageSenderPlugin, InitializingBean {
+	/**
+	 * 示远请求地址
+	 */
+	@Value("${sms.shiyuan.reqURL:1}")
+	private String reqURL;
+	/**
+	 * 示远账号
+	 */
+	@Value("${sms.shiyuan.account:1}")
+	private String account;
+	/**
+	 * 示远密码
+	 */
+	@Value("${sms.shiyuan.pwd:1}")
+	private String pswd;
+
+	// private boolean needstatus = true;//是否需要状态报告,需要true,不需要false
+	// private String product = "";//产品ID(不用填写)
+	// private String extno = "";//扩展码(不用填写)
+
+	public static String getName() {
+		return "shiyuan";
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+		// 参数检查
+		if (StringUtils.isBlank(reqURL)) {
+			throw new RuntimeException("Init parameter [reqURL] can not blank");
+		}
+		if (StringUtils.isBlank(account)) {
+			throw new RuntimeException("Init parameter [account] can not blank");
+		}
+		if (StringUtils.isBlank(pswd)) {
+			throw new RuntimeException("Init parameter [pswd] can not blank");
+		}
+	}
+
+	public void setReqURL(String reqURL) {
+		this.reqURL = reqURL;
+	}
+
+	public void setAccount(String account) {
+		this.account = account;
+	}
+
+	public void setPswd(String pswd) {
+		this.pswd = pswd;
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url,String jpushType) throws IOException {
+		try {
+			Map<String, Object> reqParams = new HashMap<String, Object>();
+			reqParams.put("account", account);
+			reqParams.put("pswd", pswd);
+			reqParams.put("mobile", receiver);
+			reqParams.put("msg", content);
+			reqParams.put("needstatus", true);
+			reqParams.put("product", "");
+			reqParams.put("extno", "");
+			reqParams.put("resptype", "json");
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			}
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke shiyuan service", e);
+		}
+		return false;
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url,String jpushType) throws IOException {
+		StringBuilder stringBuilder = new StringBuilder("");
+		for (int i = 0; i < receivers.length - 1; i++) {
+			stringBuilder.append(receivers[i]).append(",");
+		}
+		stringBuilder.append(receivers[receivers.length - 1]);
+		try {
+			Map<String, Object> reqParams = new HashMap<>();
+			reqParams.put("account", account);
+			reqParams.put("pswd", pswd);
+			reqParams.put("mobile", stringBuilder.toString().trim());
+			reqParams.put("msg", content);
+			reqParams.put("needstatus", true);
+			reqParams.put("product", "");
+			reqParams.put("extno", "");
+			reqParams.put("resptype", "json");
+			// 发起请求
+			String resultParams = HttpUtil.postForHttp(reqURL, reqParams);
+			JSONObject jsonObject = JSONObject.parseObject(resultParams);
+			if (jsonObject.get("result").equals("0")) {
+				return true;
+			}
+			throw new ThirdpartyException("示远科技短信验证码发送失败");
+		} catch (Exception e) {
+			throw new ThirdpartyException("Failed to invoke shiyuan service", e);
+		}
+	}
+
+}

+ 89 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/message/provider/YimeiSmsPlugin.java

@@ -0,0 +1,89 @@
+package com.keao.edu.thirdparty.message.provider;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.keao.edu.thirdparty.exception.ThirdpartyException;
+import com.keao.edu.thirdparty.message.MessageSenderPlugin;
+import com.keao.edu.util.date.DateUtil;
+import com.keao.edu.util.http.HttpUtil;
+
+/**
+ * 亿美短信
+ */
+@Service
+public class YimeiSmsPlugin implements MessageSenderPlugin, InitializingBean {
+
+	private Logger logger = LoggerFactory.getLogger(YimeiSmsPlugin.class);
+
+	@Value("${com.properties.sms-appId:EUCP-EMY-SMS1-DX0Y9}")
+	private String appId;
+	@Value("${com.properties.sms-secretKey:B0C8230D0F2ACC64}")
+	private String secretKey;
+	@Value("${com.properties.sms-host-dev:http://bjmtn.b2m.cn}")
+	private String host;
+
+	public static String getName() {
+		return "yimei";
+	}
+
+	private String getParam(String subject, String content, String receiver, String host) {
+		try {
+			HashMap<String, Object> param = new HashMap<String, Object>();
+			param.put("appId", appId);
+			String timestamp = DateUtil.format(new Date(), new SimpleDateFormat("yyyyMMddHHmmss"));
+			param.put("timestamp", timestamp);
+			param.put("sign", DigestUtils.md5Hex(appId + secretKey + timestamp));
+			param.put("content", content);
+			param.put("mobiles", receiver);
+			
+			long startTime = System.currentTimeMillis();
+			String result =  HttpUtil.postForHttp(host, param);
+			logger.info("调用亿美接口共消耗{}毫秒",System.currentTimeMillis() - startTime);
+			
+			return result;
+		} catch (Exception e) {
+			throw new ThirdpartyException("调用发送短信接口出现异常", e);
+		}
+	}
+
+	@Override
+	public boolean send(String subject, String content, String receiver, String url,String jpushType) throws Exception {
+		String result = getParam(subject, content, receiver, host + "/simpleinter/sendSMS");
+		JSONObject json = JSONObject.parseObject(result);
+		if ("SUCCESS".equals(json.get("code"))) {
+
+			return true;
+		} else {
+			throw new Exception(json.getString("code"));
+		}
+	}
+
+	@Override
+	public boolean batchSend(String subject, String content, String[] receivers, String url,String jpushType) throws Exception {
+		String join = StringUtils.join(receivers, ",");
+		String result = getParam(subject, content, join, host + "/simpleinter/sendSMS");
+		logger.info("调用短信接口返回:{}", result);
+		JSONObject json = JSONObject.parseObject(result);
+		if ("SUCCESS".equals(json.get("code"))) {
+			return true;
+		} else {
+			throw new Exception(json.getString("code"));
+		}
+	}
+
+	@Override
+	public void afterPropertiesSet() throws Exception {
+
+	}
+}

+ 63 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/GenerateNum.java

@@ -0,0 +1,63 @@
+package com.keao.edu.thirdparty.union;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * 生成订单号类
+ */
+public class GenerateNum {
+    // 使用单例模式,不允许直接创建实例
+    private GenerateNum() {}
+
+    // 创建一个空实例对象,类需要用的时候才赋值
+    private static GenerateNum g = null;
+
+    // 单例模式--懒汉模式
+    public static synchronized GenerateNum getInstance() {
+        if (g == null) {
+            g = new GenerateNum();
+        }
+        return g;
+    }
+
+    // 全局自增数
+    private static int count = 0;
+
+    // 每毫秒秒最多生成多少订单(最好是像9999这种准备进位的值)
+    private static final int total = 9999;
+
+    // 格式化的时间字符串
+    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+
+    // 获取当前时间年月日时分秒毫秒字符串
+    private static String getNowDateStr() {
+        return sdf.format(new Date());
+    }
+
+    // 记录上一次的时间,用来判断是否需要递增全局数
+    private static String now = null;
+
+    /*
+     * 生成一个订单号
+     */
+    public synchronized String GenerateOrderNo() {
+        String datastr = getNowDateStr();
+        if (datastr.equals(now)) {
+            count++;// 自增
+        } else {
+            count = 1;
+            now = datastr;
+        }
+        int countInteger = String.valueOf(total).length() - String.valueOf(count).length();// 算补位
+        String bu = "";// 补字符串
+        for (int i = 0; i < countInteger; i++) {
+            bu += "0";
+        }
+        bu += String.valueOf(count);
+        if (count >= total) {
+            count = 0;
+        }
+        return datastr + bu;
+    }
+}

+ 79 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/H5.java

@@ -0,0 +1,79 @@
+package com.keao.edu.thirdparty.union;
+
+import com.alibaba.fastjson.JSONObject;
+
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.util.EntityUtils;
+
+/**
+ * 银联商务H5支付
+ */
+public class H5 {
+    static String appId = "10037e6f6a4e6da4016a670fd4530012";
+    static String appKey = "f7a74b6c02ae4e1e94aaba311c04acf2";
+    static String mid = "898310148160568";
+    static String tid = "88880001";
+
+    static String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+    static String nonce = UUID.randomUUID().toString().replace("-", "");
+
+    public static byte[] hmacSHA256(byte[] data, byte[] key) throws InvalidKeyException, NoSuchAlgorithmException {
+        String algorithm = "HmacSHA256";
+        Mac mac = Mac.getInstance(algorithm);
+        mac.init(new SecretKeySpec(key, algorithm));
+        return mac.doFinal(data);
+    }
+
+    public static String getOpenBodySigForNetpay(String appId, String appKey, String timestamp, String nonce, String content) throws Exception {
+        String signatureStr = appId + timestamp + nonce + DigestUtils.sha256Hex(content);
+        byte[] localSignature = hmacSHA256(signatureStr.getBytes(), appKey.getBytes());
+        return ("authorization=OPEN-FORM-PARAM" + "&appId=" + appId + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(content, "UTF-8") + "&signature=" + URLEncoder.encode(Base64.encodeBase64String(localSignature), "UTF-8"));
+    }
+
+
+    public static String getRequestMap() throws Exception {
+        JSONObject json = new JSONObject();
+
+        json.put("instMid", "H5DEFAULT");
+        json.put("mid", mid);
+        json.put("tid", tid);
+        json.put("totalAmount", "20000");
+
+        json.put("orderDesc", "大雅乐盟培训课程");
+        // json.put("bizType", "B2B");
+        json.put("merOrderId", "1017" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + RandomStringUtils.randomNumeric(7));
+        json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+        json.put("returnUrl", "http://dev.dayaedu.com");
+
+        String param = getOpenBodySigForNetpay(appId, appKey, timestamp, nonce, json.toString());
+        return "http://58.247.0.18:29015/v1/netpay/trade/h5-pay?" + param;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+
+        System.out.println(getRequestMap());
+
+    }
+}
+

+ 60 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/Mp.java

@@ -0,0 +1,60 @@
+package com.keao.edu.thirdparty.union;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.UUID;
+
+/**
+ * 银联商务公众号支付
+ */
+public class Mp {
+    static String appId = "10037e6f6a4e6da4016a62a47e51000c";
+    static String appKey = "b4b70d123a724972bc21f445b0b9f75c";
+    static String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+    static String nonce = UUID.randomUUID().toString().replace("-", "");
+
+    public static byte[] hmacSHA256(byte[] data, byte[] key) throws InvalidKeyException, NoSuchAlgorithmException {
+        String algorithm = "HmacSHA256";
+        Mac mac = Mac.getInstance(algorithm);
+        mac.init(new SecretKeySpec(key, algorithm));
+        return mac.doFinal(data);
+    }
+
+    public static String getOpenBodySigForNetpay(String appId, String appKey, String timestamp, String nonce, String content) throws Exception {
+        String signatureStr = appId + timestamp + nonce + DigestUtils.sha256Hex(content);
+        byte[] localSignature = hmacSHA256(signatureStr.getBytes(), appKey.getBytes());
+        return ("authorization=OPEN-FORM-PARAM" + "&appId=" + appId + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(content, "UTF-8") + "&signature=" + URLEncoder.encode(Base64.encodeBase64String(localSignature), "UTF-8"));
+    }
+
+    public static void main(String[] args) throws Exception {
+        JSONObject json = new JSONObject();
+
+        json.put("instMid", "YUEDANDEFAULT");
+        json.put("mid", "898460107420248");
+        json.put("tid", "00000001");
+        json.put("totalAmount", 4000);
+
+        json.put("orderDesc", "大雅乐盟培训订单");
+        // json.put("bizType", "B2B");
+        json.put("merOrderId", "1017" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + RandomStringUtils.randomNumeric(7));
+        json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+
+
+        String param = getOpenBodySigForNetpay(appId, appKey, timestamp, nonce, json.toString());
+        System.out.println("http://58.247.0.18:29015/v1/netpay/webpay/pay?" + param);
+//        GetOpenBodySig.sendGet("http://58.247.0.18:29015/v1/netpay/webpay/pay?"+param);
+        System.out.println(json.toString());
+    }
+}
+

+ 81 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/NotifyMsg.java

@@ -0,0 +1,81 @@
+package com.keao.edu.thirdparty.union;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 异步通知具体信息
+ */
+public class NotifyMsg {
+    private BigDecimal totalAmount;//订单总金额(分)
+    private String merOrderId;//商户订单号
+    private Date payTime;//支付时间
+    private String seqId; //支付系统交易流水号
+    private String status; //交易状态,NEW_ORDER-新订单 UNKNOWN-不明交易状态 TRADE_CLOSED-关闭的交易 WAIT_BUYER_PAY-交易创建等待付款 TRADE_SUCCESS-交易成功
+    private String targetOrderId; //渠道订单号
+    private String targetSys;//支付渠道,WXPay,Alipay 2.0等
+
+
+    public BigDecimal getTotalAmount() {
+        return totalAmount;
+    }
+
+    public void setTotalAmount(BigDecimal totalAmount) {
+        this.totalAmount = totalAmount;
+    }
+
+    public String getMerOrderId() {
+        return merOrderId;
+    }
+
+    public void setMerOrderId(String merOrderId) {
+        this.merOrderId = merOrderId;
+    }
+
+    public Date getPayTime() {
+        return payTime;
+    }
+
+    public void setPayTime(Date payTime) {
+        this.payTime = payTime;
+    }
+
+    public String getSeqId() {
+        return seqId;
+    }
+
+    public void setSeqId(String seqId) {
+        this.seqId = seqId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getTargetOrderId() {
+        return targetOrderId;
+    }
+
+    public void setTargetOrderId(String targetOrderId) {
+        this.targetOrderId = targetOrderId;
+    }
+
+    public String getTargetSys() {
+        return targetSys;
+    }
+
+    public void setTargetSys(String targetSys) {
+        this.targetSys = targetSys;
+    }
+
+    @Override
+    public String toString() {
+        return ToStringBuilder.reflectionToString(this);
+    }
+}

+ 145 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/UnionPay.java

@@ -0,0 +1,145 @@
+package com.keao.edu.thirdparty.union;
+
+import com.alibaba.fastjson.JSONObject;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.math.BigDecimal;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+
+/**
+ * 银联商务主扫
+ */
+public class UnionPay {
+
+    private UnionPayFeignService unionPayFeignService;
+
+    static String aliPayUrl = "http://58.247.0.18:29015/v1/netpay/trade/h5-pay";//支付宝
+    static String qmfPayUrl = "http://58.247.0.18:29015/v1/netpay/qmf/h5-pay";//银联无卡
+    static String H5AppId = "10037e6f6a4e6da4016a670fd4530012";
+    static String h5AppKey = "f7a74b6c02ae4e1e94aaba311c04acf2";
+    static String h5Mid = "898310148160568";
+    static String h5Tid = "88880001";
+
+    static String wpPayUrl = "http://58.247.0.18:29015/v1/netpay/webpay/pay";//微信
+    static String wpAppId = "10037e6f6a4e6da4016a62a47e51000c";
+    static String wpAppKey = "b4b70d123a724972bc21f445b0b9f75c";
+    static String wpMid = "898460107420248";
+    static String wpTid = "00000001";
+
+    static String queryUrl = "http://58.247.0.18:29015/v1/netpay/query"; //订单查询地址
+
+    static String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
+    static String nonce = UUID.randomUUID().toString().replace("-", "");
+
+    public UnionPay(UnionPayFeignService unionPayFeignService) {
+        this.unionPayFeignService = unionPayFeignService;
+    }
+
+    private static byte[] hmacSHA256(byte[] data, byte[] key) throws InvalidKeyException, NoSuchAlgorithmException {
+        String algorithm = "HmacSHA256";
+        Mac mac = Mac.getInstance(algorithm);
+        mac.init(new SecretKeySpec(key, algorithm));
+        return mac.doFinal(data);
+    }
+
+    private static String getOpenBodySig(String appId, String appKey, String timestamp, String nonce, String content, String method) throws Exception {
+        String signatureStr = appId + timestamp + nonce + DigestUtils.sha256Hex(content);
+        byte[] localSignature = hmacSHA256(signatureStr.getBytes(), appKey.getBytes());
+        if (method.toUpperCase().equals("POST")) {
+            return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + Base64.encodeBase64String(localSignature) + "\"");
+        } else {
+            return ("authorization=OPEN-FORM-PARAM" + "&appId=" + appId + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(content, "UTF-8") + "&signature=" + URLEncoder.encode(Base64.encodeBase64String(localSignature), "UTF-8"));
+        }
+
+    }
+
+
+    /**
+     * 获取支付链接的Map
+     *
+     * @param amount
+     * @param orderNo
+     * @param notifyUrl
+     * @param returnUrl
+     * @param orderSubject
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, String> getPayMap(BigDecimal amount, String orderNo, String notifyUrl, String returnUrl, String orderSubject) throws Exception {
+        Map<String, String> PayMap = new HashMap<>();
+        JSONObject json = new JSONObject();
+        //H5支付链接生成
+        json.put("totalAmount", amount.multiply(new BigDecimal("100")).intValue());
+        json.put("instMid", "H5DEFAULT");
+        json.put("mid", h5Mid);
+        json.put("tid", h5Tid);
+        json.put("orderDesc", orderSubject);
+        json.put("merOrderId", "1017" + orderNo);
+        json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+        json.put("expireTime", DateFormatUtils.format(new Date().getTime() + 300000, "yyyy-MM-dd HH:mm:ss"));
+        json.put("notifyUrl", notifyUrl);
+        json.put("returnUrl", returnUrl);
+        String param = getOpenBodySig(H5AppId, h5AppKey, timestamp, nonce, json.toString(), "GET");
+        PayMap.put("aliPay", aliPayUrl + "?" + param);
+        PayMap.put("qmfPay", qmfPayUrl + "?" + param);
+
+        //微信公众号支付链接生成
+        json.put("instMid", "YUEDANDEFAULT");
+        json.put("mid", wpMid);
+        json.put("tid", wpTid);
+
+        param = getOpenBodySig(wpAppId, wpAppKey, timestamp, nonce, json.toString(), "GET");
+        PayMap.put("weChatPay", wpPayUrl + "?" + param);
+        return PayMap;
+    }
+
+    /**
+     * 订单查询
+     *
+     * @param orderNo 自己系统订单号
+     * @return 1017201910111756231647562047 测试订单号
+     */
+    public Map<String, Object> query(String orderNo) throws Exception {
+        JSONObject json = new JSONObject();
+        json.put("instMid", "H5DEFAULT");
+        json.put("mid", h5Mid);
+        json.put("tid", h5Tid);
+        json.put("merOrderId", "1017" + orderNo);
+        json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
+
+        String authorization = getOpenBodySig(wpAppId, wpAppKey, timestamp, nonce, json.toString(), "POST");
+        HashMap<String, String> header = new HashMap<>();
+        header.put("Authorization", authorization);
+        header.put("Content-Type", "application/json; charset=utf-8");
+        Map query = unionPayFeignService.query(json.getInnerMap(), header);
+        return query;
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        String orderNo = "1017" + new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + RandomStringUtils.randomNumeric(7);
+
+        System.out.println(orderNo);
+
+        Map<String, String> payMap = getPayMap(new BigDecimal("0.01"), orderNo, "http://pay.dayaedu.com/pay/notify", "http://dev.daya.com", "大雅测试订单");
+        System.out.println("weChat= " + payMap.get("weChatPay"));
+        System.out.println("H5= " + payMap.get("aliPay"));
+        System.out.println("qmfPay= " + payMap.get("qmfPay"));
+    }
+}
+

+ 15 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/union/UnionPayFeignService.java

@@ -0,0 +1,15 @@
+package com.keao.edu.thirdparty.union;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+
+@FeignClient(value = "UnionPayFeignService", url = "http://58.247.0.18:29015")
+public interface UnionPayFeignService {
+
+    @RequestMapping(name = "查询订单", value = "/v1/netpay/query", method = RequestMethod.POST)
+    Map query(@RequestBody Map body, @RequestHeader Map Header);
+
+}

+ 296 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/CFCARAUtil.java

@@ -0,0 +1,296 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Map;
+
+import javax.crypto.spec.SecretKeySpec;
+
+import org.springframework.core.io.ClassPathResource;
+
+import cfca.sadk.algorithm.common.Mechanism;
+import cfca.sadk.algorithm.common.PKIException;
+import cfca.sadk.lib.crypto.JCrypto;
+import cfca.sadk.system.FileHelper;
+import cfca.sadk.util.Base64;
+import cfca.sadk.util.CertUtil;
+import cfca.sadk.util.EncryptUtil;
+import cfca.sadk.util.EnvelopeUtil;
+import cfca.sadk.util.KeyUtil;
+import cfca.sadk.util.Signature;
+import cfca.sadk.x509.certificate.X509Cert;
+
+
+public class CFCARAUtil {
+    private static final String deviceName = JCrypto.JSOFT_LIB;
+    private static cfca.sadk.lib.crypto.Session session = null;
+
+
+    static {
+        try {
+            JCrypto jCrypto = JCrypto.getInstance();
+            jCrypto.initialize(deviceName, null);
+            session = jCrypto.openSession(deviceName);
+        } catch (PKIException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+    /******* p1 *********/
+    /**
+     *
+     * p1消息签名
+     * @param :message
+     * @return
+     * @throws Exception
+     *
+     */
+    public static String signMessageByP1(String message, String pfxPath, String passWord) throws Exception{
+       // File file = new ClassPathResource(pfxPath).getFile();
+
+
+        PrivateKey userPriKey = KeyUtil.getPrivateKeyFromPFX(CFCARAUtil.class.getClassLoader().getResourceAsStream(pfxPath), passWord);
+        Signature signature = new Signature();
+        byte[] base64P7SignedData = signature.p1SignMessage(Mechanism.SHA256_RSA, message.getBytes("UTF-8"), userPriKey, session);
+        return new String(base64P7SignedData);
+    }
+
+    /**
+     * p1消息校验(公钥证书验签)
+     * @param :beforeSignedData
+     * @param :afterSignedData
+     * @param :certPath
+     * @return
+     * @throws Exception
+     */
+    public static boolean verifyMessageByP1(String beforeSignedData, String afterSignedData, String certPath) throws Exception{
+        //File file = new ClassPathResource(certPath).getFile();
+        X509Cert cert = new X509Cert(CFCARAUtil.class.getClassLoader().getResourceAsStream(certPath));
+        PublicKey publicKey = cert.getPublicKey();
+        Signature signature = new Signature();
+        return signature.p1VerifyMessage(Mechanism.SHA256_RSA, beforeSignedData.getBytes("UTF-8"), afterSignedData.getBytes("UTF-8"), publicKey, session);
+    }
+    /**
+     * p1消息校验(公钥证书验签)
+     * @return
+     * @throws Exception
+     */
+    public static boolean verifyMessageByP1Location(String beforeSignedData, String afterSignedData, String certPath) throws Exception{
+        X509Cert cert = new X509Cert(new FileInputStream(certPath));
+        PublicKey publicKey = cert.getPublicKey();
+        Signature signature = new Signature();
+        return signature.p1VerifyMessage(Mechanism.SHA256_RSA, beforeSignedData.getBytes("UTF-8"), afterSignedData.getBytes("UTF-8"), publicKey, session);
+    }
+
+    /**
+     *
+     * p1消息校验(公钥字符串验签)
+     * @param :beforeSignedData
+     * @param :afterSignedData
+     * @param :publicKeyStr
+     * @return
+     * @throws Exception
+     *
+     */
+    public static boolean verifyMessageByP1AndPubKey(String beforeSignedData, String afterSignedData, String publicKeyStr) throws Exception{
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyStr));
+        PublicKey publicKey = keyFactory.generatePublic(keySpec);
+        Signature signature = new Signature();
+        return signature.p1VerifyMessage(Mechanism.SHA256_RSA, beforeSignedData.getBytes("UTF-8"), afterSignedData.getBytes("UTF-8"), publicKey, session);
+    }
+
+    /********* RSA_PKCS ***********/
+    /**
+     *  RSA证书加密消息
+     *  RSA_PKCS公钥加密
+     * @param :message
+     * @throws Exception
+     */
+    public static String encryptMessageByRSA_PKCS(String message, String certPath) throws Exception{
+        File file = new ClassPathResource(certPath).getFile();
+        X509Cert cert = new X509Cert(new FileInputStream(file));
+        PublicKey userPubKey = cert.getPublicKey();
+        Mechanism mechanism = new Mechanism(Mechanism.RSA_PKCS);
+        byte[] encryptedData = EncryptUtil.encrypt(mechanism, userPubKey, message.getBytes("UTF-8"), session);
+        return new String(encryptedData);
+    }
+
+    /**
+     *  RSA证书加密消息
+     *  RSA_PKCS公钥字符串加密
+     * @param :message
+     * @throws Exception
+     */
+    public static String encryptMessageByRSA_PKCS_String(String message, String publicKeyStr) throws Exception{
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.decode(publicKeyStr));
+        PublicKey userPubKey = keyFactory.generatePublic(keySpec);
+
+//        File file = new ClassPathResource(certPath).getFile();
+//        X509Cert cert = new X509Cert(new FileInputStream(file));
+//        PublicKey userPubKey = cert.getPublicKey();
+        Mechanism mechanism = new Mechanism(Mechanism.RSA_PKCS);
+        byte[] encryptedData = EncryptUtil.encrypt(mechanism, userPubKey, message.getBytes("UTF-8"), session);
+        return new String(encryptedData);
+    }
+
+    /**
+     * RSA证书解密消息
+     * RSA_PKCS私钥解密
+     * @param :key
+     * @param :message
+     * @throws Exception
+     */
+    public static String decryptMessageByRSA_PKCS(String message, String pfxPath, String passWord) throws Exception{
+        File file = new ClassPathResource(pfxPath).getFile();
+        PrivateKey userPriKey = KeyUtil.getPrivateKeyFromPFX(new FileInputStream(file), passWord);
+        Mechanism mechanism = new Mechanism(Mechanism.RSA_PKCS);
+        byte[] dataBytes = message.getBytes("UTF-8");
+        byte[] encryptedData = EncryptUtil.decrypt(mechanism, userPriKey, dataBytes, session);
+        return new String(encryptedData);
+    }
+
+    /********* RC4 **********/
+    /**
+     * RSA证书加密消息
+     * RC4对称加密
+     * @param :message
+     * @return
+     * @throws Exception
+     */
+    public static String encryptMessageByRC4(String message, String pfxPath, String passWord) throws Exception{
+        byte[] data = FileHelper.read(pfxPath);
+        Key key = new SecretKeySpec(Base64.decode(Base64.encode(data)), "RC4");
+        Mechanism mechanism = new Mechanism(Mechanism.RC4);
+        byte[] dataBytes = message.getBytes("UTF-8");
+        byte[] encryptedData = EncryptUtil.encrypt(mechanism, key, dataBytes, session);
+        return new String(encryptedData);
+
+    }
+
+    /**
+     * RSA证书解密消息
+     * RC4对称解密
+     * @param :message
+     * @return
+     * @throws Exception
+     */
+    public static String decryptMessageByRC4(String message, String pfxPath, String passWord) throws Exception{
+        byte[] data = FileHelper.read(pfxPath);
+        Key key = new SecretKeySpec(Base64.decode(Base64.encode(data)), "RC4");
+        Mechanism mechanism = new Mechanism(Mechanism.RC4);
+        byte[] encryptedData = EncryptUtil.decrypt(mechanism, key, message.getBytes("UTF-8"), session);
+        return new String(encryptedData);
+    }
+
+    /****** p7 ******/
+    /**
+     * P7 分离式文件签名(签名)
+     */
+    public static String signData(String toBeSigned, String certPath, String certPass) throws Exception {
+        X509Cert cert = CertUtil.getCertFromPFX(certPath, certPass);
+        PrivateKey priKey = KeyUtil.getPrivateKeyFromPFX(certPath, certPass);
+        Signature signature = new Signature();
+        return new String(signature.p7SignMessageDetach(Mechanism.SHA256_RSA, toBeSigned.getBytes("UTF8"), priKey, cert, session), "UTF8");
+    }
+
+    /**
+     * P7 分离式消息校验(验签)
+     */
+    public static boolean verifySignature(String data, String signdata) throws Exception {
+        Signature signature = new Signature();
+        return signature.p7VerifyMessageDetach(data.getBytes("UTF8"), signdata.getBytes("UTF8"), session);
+    }
+
+    /**
+     * 消息数字信封(公钥加密)
+     */
+    public static String encryptData(String data, String certPath) throws Exception {
+        // X509Cert cert = CertUtil.getCertFromPFX(certPath, certPass);
+        X509Cert cert = new X509Cert(new FileInputStream(certPath));
+        X509Cert[] recvcerts = new X509Cert[]{ cert };
+        return new String(EnvelopeUtil.envelopeMessage(data.getBytes("UTF8"), Mechanism.RC4, recvcerts, session), "UTF8");
+    }
+
+    /**
+     * 数据解密
+     */
+    public static String decryptData(String encryptedData, String certPath, String certPass) throws Exception {
+        PrivateKey priKey = KeyUtil.getPrivateKeyFromPFX(certPath, certPass);
+        X509Cert cert = CertUtil.getCertFromPFX(certPath, certPass);
+        return new String(EnvelopeUtil.openEvelopedMessage(encryptedData.getBytes("UTF8"), priKey, cert, session), "UTF8");
+    }
+
+
+
+    /**
+     * 拼接字符串方法
+     * @param map
+     * @param connector
+     * @return
+     */
+    public static String joinMapValue(Map<String, Object> map, char connector)	{
+        StringBuffer b = new StringBuffer();
+        for (Map.Entry<String, Object> entry : map.entrySet()){
+            b.append(entry.getKey());
+            b.append('=');
+            if (entry.getValue() != null){
+                b.append(entry.getValue());
+            }
+            b.append(connector);
+        }
+        return b.toString().substring(0, b.length()-1);
+    }
+
+
+    public static void main(String[] args) throws Exception {
+        // 实际地址,请改为项目路径
+        String pfxPath = "D:\\certificate\\168885_test.pfx";
+        // 实际地址,请改为项目路径
+        String certPath = "D:\\certificate\\168885_test.cer";
+        String password = "123123";
+        String plaintext = "幸福是你有食物吃,睡觉的地方,有所爱的人。";
+        String plaintext1 = "幸福是你有食物吃,睡觉的地方,有所爱的人";
+
+        /******* p1 ******/
+        //签名
+        String base64P7SignedData = signMessageByP1(plaintext, pfxPath, password);
+        //验签
+        boolean verifyByp1 = verifyMessageByP1(plaintext, base64P7SignedData, certPath);
+        System.out.println("p1-cert:"+verifyByp1);
+
+        //验签
+        String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApSC4H4PvPuS9GJq9chCHq"
+                + "PHb+MK2dYRwVlU+9LJHhEA0mbmkhbSyvcakHuvrXtrBCBt5GMSU2BQeZy2IqQoZDJ"
+                + "Cn5CHufgMUpyMD7qvRo+GOg3GRC3k506ebb/Od/LL0eMAcCiOcCC7HHiPGP44VtBs"
+                + "OgqX22/BSAxyK93bnQbb4+8sc4id0io403rLjBle7vIzrNJtqftuTSQJMm/OmRDvf"
+                + "hg0asdUZYCsb3TdhRqO5hblDl/s/5b6gFTYcgPAw9qKdknqAWGqHP/J6i3GDAqedq"
+                + "7lFuDvkqSnYnWgVzpv9luWzrvXYOl2K4fvDSl9JIXHUMMz9cELEJjmq7yM+fQIDAQ"
+                + "AB";
+        boolean verifyByp1PublicKeyStr = verifyMessageByP1AndPubKey(plaintext, base64P7SignedData, publicKeyStr);
+        System.out.println("p1-PublicKeyStr:"+verifyByp1PublicKeyStr);
+
+        File file = new File("D:\\certificate\\168885_test.cer");
+        CertificateFactory cf = CertificateFactory.getInstance("X.509");
+        X509Certificate cert = (X509Certificate)cf.generateCertificate(new FileInputStream(file));
+        PublicKey publicKey = cert.getPublicKey();
+        String publicKeyString = Base64.toBase64String(publicKey.getEncoded());
+        System.out.println("-----------------公钥--------------------");
+        System.out.println(publicKeyString);
+        System.out.println("-----------------公钥--------------------");
+    }
+
+
+
+
+
+}

+ 384 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/DateUtils.java

@@ -0,0 +1,384 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
+	
+	private static String[] parsePatterns = {
+		"yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
+		"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+		"yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+	public static final String YYYY_MM_DD = "yyyyMMdd";
+	public static final String HH_SS_MM = "HHssmm";
+	public static final String YYYY_MM_DD_DEF = "yyyy-MM-dd";
+	public static final String YYYY_MM_DD_HH_MM_SS = "yyyyMMddHHmmss";
+	public static final String DATE_WEB_FORMAT = "yyyy-MM-dd HH:mm:ss";
+	public static final String DATE_WEB_FORMAT_NO_SS = "yyyy-MM-dd HH:mm";
+	public static final String E_MMM_DD_HH_MM_SS_Z_YYYY = "E MMM dd hh:mm:ss z yyyy";//日期格式 "Tue Sep 26 13:56:19 CST 2017"
+	public static final String YYYY_MM_DD_HH_MM_SS_SSS = "yyyyMMddHHmmssSSS";
+
+	public static void main(String[] args) {
+		getTimeOfY0(new Date());
+		int i=0;
+	}
+
+	public static String getDate() {
+		return getDate("yyyy-MM-dd");
+	}
+
+	public static String getDate(String pattern) {
+		return DateFormatUtils.format(new Date(), pattern);
+	}
+
+
+
+	public static String formatDate(Date date, Object... pattern) {
+		if (date == null)
+			return null;
+
+		String formatDate;
+		if (pattern != null && pattern.length > 0) {
+			formatDate = DateFormatUtils.format(date, pattern[0].toString());
+		} else {
+			formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
+		}
+		return formatDate;
+	}
+
+	public static String formatDateTime(Date date) {
+		return formatDate(date, "yyyy-MM-dd HH:mm:ss");
+	}
+
+	public static Date getTimeOfY0(Date date) {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.set(Calendar.MONTH, 0);
+		cal.set(Calendar.DATE, 1);
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	public static Date getTimeOfM0(Date date) {
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.set(Calendar.DATE, 1);
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	public static Date getTimeOfD0(Date date){
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	public static Date getTimeOfH0(Date date){
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	public static Date getFirstTimeOfMonth(Date date){
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.set(Calendar.DAY_OF_MONTH,
+				cal.getActualMinimum(Calendar.DAY_OF_MONTH));
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	public static Date getLastTimeOfMonth(Date date){
+		Calendar cal = Calendar.getInstance();
+		cal.setTime(date);
+		cal.add(Calendar.MONTH, 1);
+		cal.set(Calendar.DAY_OF_MONTH,
+				cal.getActualMinimum(Calendar.DAY_OF_MONTH));
+		cal.set(Calendar.HOUR_OF_DAY, 0);
+		cal.set(Calendar.MINUTE, 0);
+		cal.set(Calendar.SECOND, 0);
+		cal.set(Calendar.MILLISECOND, 0);
+		return  cal.getTime();
+	}
+
+	/*是否为指定月份的最后一天*/
+	public static boolean isLastDayOfMonth(Date date) {
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(date);
+		calendar.set(Calendar.DATE, (calendar.get(Calendar.DATE) + 1));
+		if (calendar.get(Calendar.DAY_OF_MONTH) == 1) {
+			return true;
+		}
+		return false;
+	}
+
+	/*是否为本月第一天*/
+	public static boolean isFirstDayOfThisMonth(Date date) {
+		if(date==null){
+			return false;
+		}
+		String now = formatDate(date,"yyyy-MM-dd");
+		Calendar calendar = Calendar.getInstance();
+		calendar.setTime(new Date());
+		calendar.set(Calendar.DAY_OF_MONTH,1);
+		Date firstDate = calendar.getTime();
+		String first = formatDate(firstDate,"yyyy-MM-dd");
+
+		if(now.equals(first)){
+			return true;
+		}else {
+			return false;
+		}
+	}
+
+	public static String getYearAndMonth(Date date){
+		String ym = formatDate(date,"yyyy-MM");
+		return ym;
+	}
+
+	public static String getTime() {
+		return formatDate(new Date(), "HH:mm:ss");
+	}
+
+	public static String getDateTime() {
+		return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
+	}
+
+	public static String getYear() {
+		return formatDate(new Date(), "yyyy");
+	}
+
+	public static String getMonth() {
+		return formatDate(new Date(), "MM");
+	}
+
+	public static String getDay() {
+		return formatDate(new Date(), "dd");
+	}
+
+	public static String getHour(Date date) {
+		return formatDate(date, "HH");
+	}
+
+	public static String getWeek() {
+		return formatDate(new Date(), "E");
+	}
+	public static String getWeekByParam(Date date) {
+		return formatDate(date, "E");
+	}
+
+	public static Date parseDate(Object str) {
+		if (str == null){
+			return null;
+		}
+		try {
+			return parseDate(str.toString(), parsePatterns);
+		} catch (ParseException e) {
+			return null;
+		}
+	}
+
+	public static long pastDays(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(24*60*60*1000);
+	}
+
+	public static long pastHour(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(60*60*1000);
+	}
+
+	public static long pastMinutes(Date date) {
+		long t = new Date().getTime()-date.getTime();
+		return t/(60*1000);
+	}
+
+    public static String formatDateTime(long timeMillis){
+		long day = timeMillis/(24*60*60*1000);
+		long hour = (timeMillis/(60*60*1000)-day*24);
+		long min = ((timeMillis/(60*1000))-day*24*60-hour*60);
+		long s = (timeMillis/1000-day*24*60*60-hour*60*60-min*60);
+		long sss = (timeMillis-day*24*60*60*1000-hour*60*60*1000-min*60*1000-s*1000);
+		return (day>0?day+",":"")+hour+":"+min+":"+s+"."+sss;
+    }
+
+	public static double getDistanceOfTwoDate(Date before, Date after) {
+		long beforeTime = before.getTime();
+		long afterTime = after.getTime();
+		return (afterTime - beforeTime) / (1000 * 60 * 60 * 24);
+	}
+
+	/**
+	 *  日期大小比较
+	 * @param date1
+	 * @param date2
+	 * @return date2 == date1-->0
+	 * @return date2 > date1-->1
+	 * @return date2 < date1-->-1
+	 * @return -2 异常
+	 */
+	public static int dateStringCompare(Date date1,String date2) {
+		DateFormat df = new SimpleDateFormat("yyyy-MM");
+		try {
+			Date dt1 = df.parse(date2);
+			Date dt2 = df.parse(df.format(date1));;
+			if (dt1.getTime()>dt2.getTime()){
+				return  1;
+			}else if (dt1.getTime()== dt2.getTime()){
+				return  0;
+			}else {
+				return  -1;
+			}
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return  2;
+	}
+
+	/**
+	 * 取得当月天数
+	 * */
+	public static int getCurrentMonthLastDay()
+	{
+		Calendar a = Calendar.getInstance();
+		a.set(Calendar.DATE, 1);
+		a.roll(Calendar.DATE, -1);
+		int maxDate = a.get(Calendar.DATE);
+		return maxDate;
+	}
+
+
+	/**
+	 * 字符串转换成日期
+	 * @param str
+	 * @param formatType
+	 * @return
+	 */
+	public static Date StrToDate(String str,String formatType) {
+
+		SimpleDateFormat format = new SimpleDateFormat(formatType);
+		Date date = null;
+		try {
+			//date = format.parse(new SimpleDateFormat(formatType).format(str));
+			date = format.parse(str);
+		} catch (ParseException e) {
+			e.printStackTrace();
+		}
+		return date;
+	}
+
+	public static List<String> getWeekend(Integer year){
+		List<String> list = new ArrayList<String>();
+		try{
+			SimpleDateFormat df=new SimpleDateFormat("yyyy-mm-dd");
+			Date date=null;
+			Calendar calendar=Calendar.getInstance();
+			int totalDay;
+			if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0){//闰年的判断规则
+				totalDay=366;
+			}else{
+				totalDay=365;
+			}
+			date=df.parse(year+"-01-01");
+			Calendar cal = Calendar.getInstance();
+			cal.setTime(date);
+			for(int i=0;i<totalDay;i++){
+				if(cal.get(Calendar.DAY_OF_WEEK)==Calendar.SATURDAY||cal.get(Calendar.DAY_OF_WEEK)==Calendar.SUNDAY) {
+					list.add(DateUtils.formatDate(cal.getTime(),"yyyy-MM-dd"));
+				}
+				cal.add(Calendar.DAY_OF_MONTH,1);
+			}
+		}catch(ParseException e){
+			e.printStackTrace();
+		}
+
+		return list;
+	}
+
+	/**
+	 * 使用SimpleDateFormat类对时间字符串的合法性进行校验
+	 *
+	 * @param dateStr
+	 *            将要被校验合法性的时间字符串,格式:yyyyMMddHHmmss
+	 */
+	public static Boolean checkLegalityInClassSimpleDateFormat(String dateStr,String format) {
+		SimpleDateFormat sdf = new SimpleDateFormat(format);
+		try {
+			Date realDate = sdf.parse(dateStr);
+			if (dateStr.equals(sdf.format(realDate))) {
+				return true;
+			} else {
+				return false;
+			}
+			// System.out.println(realDate.toString());
+		} catch (ParseException e) {
+			e.printStackTrace();
+			return false;
+		}
+	}// end method - checkLegalityInClassSimpleDateFormat
+
+    /**
+     * 判断日期是否为周末
+     *
+     * @param date 入参日期
+     * @return true:为周末
+     */
+    public static boolean isWeekend(Date date) {
+        if (date == null)
+            return false;
+
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        return cal.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY || cal.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY;
+    }
+
+    /*
+ * 计算时间差
+ */
+    public static int getTwoDayTimes(String fromDate ,String toDate) {
+        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
+        try {
+            long from = simpleFormat.parse(fromDate).getTime();
+            long to = simpleFormat.parse(toDate).getTime();
+            int seconds = (int) ((to - from)/(1000));
+            return seconds;
+        } catch (ParseException e) {
+            e.printStackTrace();
+            return -1;
+        }
+    }
+    
+    public static String getDayForAfter(Date d, int day){
+    	Calendar now =Calendar.getInstance();
+	    now.setTime(d);
+	    now.set(Calendar.DATE,now.get(Calendar.DATE)+day);
+	    SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd");
+	    return simpleFormat.format(now.getTime());
+
+    }
+
+}

+ 72 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/Intfc.java

@@ -0,0 +1,72 @@
+package com.keao.edu.thirdparty.yqpay;
+
+/**
+ * 提现信息
+ */
+
+public class Intfc {
+
+    private String wdMerNo; //提现商户号
+    private String amount; //提现金额
+    private String cardNo; //提现银行卡号
+    private String phone; //预留手机号(选填)
+    private String cardType; //卡类型 0-个人银行卡,1-企业银行卡。(选填)
+    private String seqNo; //流水号(选填)
+    private String smsCode; //验证码(选填)
+
+    public String getWdMerNo() {
+        return wdMerNo;
+    }
+
+    public void setWdMerNo(String wdMerNo) {
+        this.wdMerNo = wdMerNo;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getCardNo() {
+        return cardNo;
+    }
+
+    public void setCardNo(String cardNo) {
+        this.cardNo = cardNo;
+    }
+
+    public String getPhone() {
+        return phone;
+    }
+
+    public void setPhone(String phone) {
+        this.phone = phone;
+    }
+
+    public String getCardType() {
+        return cardType;
+    }
+
+    public void setCardType(String cardType) {
+        this.cardType = cardType;
+    }
+
+    public String getSeqNo() {
+        return seqNo;
+    }
+
+    public void setSeqNo(String seqNo) {
+        this.seqNo = seqNo;
+    }
+
+    public String getSmsCode() {
+        return smsCode;
+    }
+
+    public void setSmsCode(String smsCode) {
+        this.smsCode = smsCode;
+    }
+}

+ 57 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/Msg.java

@@ -0,0 +1,57 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+
+public class Msg {
+
+    private String code;
+    private String msg;
+    private String responseType;
+    private String responseParameters;
+    private String sign;
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getResponseType() {
+        return responseType;
+    }
+
+    public void setResponseType(String responseType) {
+        this.responseType = responseType;
+    }
+
+    public String getResponseParameters() {
+        return responseParameters;
+    }
+
+    public void setResponseParameters(String responseParameters) {
+        this.responseParameters = responseParameters;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+    
+    @Override
+    public String toString() {
+    	return ToStringBuilder.reflectionToString(this);
+    }
+}

+ 81 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/NotifyMsg.java

@@ -0,0 +1,81 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import java.math.BigDecimal;
+
+/**
+ * 异步通知具体信息
+ */
+public class NotifyMsg {
+    private String merMerOrderNo;
+    private BigDecimal payAmount;
+    private String orderNo;
+    private String sellerNo;
+    private String buyerNo;
+    private String qyfcustUniqueNo;
+    private String tradeFee;
+    private String channelType;
+
+    public String getMerMerOrderNo() {
+        return merMerOrderNo;
+    }
+
+    public void setMerMerOrderNo(String merMerOrderNo) {
+        this.merMerOrderNo = merMerOrderNo;
+    }
+
+    public BigDecimal getPayAmount() {
+        return payAmount;
+    }
+
+    public void setPayAmount(BigDecimal payAmount) {
+        this.payAmount = payAmount;
+    }
+
+    public String getOrderNo() {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+    }
+
+    public String getSellerNo() {
+        return sellerNo;
+    }
+
+    public void setSellerNo(String sellerNo) {
+        this.sellerNo = sellerNo;
+    }
+
+    public String getBuyerNo() {
+        return buyerNo;
+    }
+
+    public void setBuyerNo(String buyerNo) {
+        this.buyerNo = buyerNo;
+    }
+
+    public String getQyfcustUniqueNo() {
+        return qyfcustUniqueNo;
+    }
+
+    public void setQyfcustUniqueNo(String qyfcustUniqueNo) {
+        this.qyfcustUniqueNo = qyfcustUniqueNo;
+    }
+
+    public String getTradeFee() {
+        return tradeFee;
+    }
+
+    public void setTradeFee(String tradeFee) {
+        this.tradeFee = tradeFee;
+    }
+
+    public String getChannelType() {
+        return channelType;
+    }
+
+    public void setChannelType(String channelType) {
+        this.channelType = channelType;
+    }
+}

+ 68 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/RspMsg.java

@@ -0,0 +1,68 @@
+package com.keao.edu.thirdparty.yqpay;
+
+public class RspMsg {
+
+    private String merOrderNo;
+    private String merMerOrderNo;
+    private String payUrlSAO;
+    private String qrCode;
+    private String apiStr;
+    private String tradeNo;
+    private String payHtml;
+
+    public String getMerOrderNo() {
+        return merOrderNo;
+    }
+
+    public void setMerOrderNo(String merOrderNo) {
+        this.merOrderNo = merOrderNo;
+    }
+
+    public String getMerMerOrderNo() {
+        return merMerOrderNo;
+    }
+
+    public void setMerMerOrderNo(String merMerOrderNo) {
+        this.merMerOrderNo = merMerOrderNo;
+    }
+
+    public String getPayUrlSAO() {
+        return payUrlSAO;
+    }
+
+    public void setPayUrlSAO(String payUrlSAO) {
+        this.payUrlSAO = payUrlSAO;
+    }
+
+    public String getQrCode() {
+        return qrCode;
+    }
+
+    public void setQrCode(String qrCode) {
+        this.qrCode = qrCode;
+    }
+
+    public String getApiStr() {
+        return apiStr;
+    }
+
+    public void setApiStr(String apiStr) {
+        this.apiStr = apiStr;
+    }
+
+    public String getTradeNo() {
+        return tradeNo;
+    }
+
+    public void setTradeNo(String tradeNo) {
+        this.tradeNo = tradeNo;
+    }
+
+    public String getPayHtml() {
+        return payHtml;
+    }
+
+    public void setPayHtml(String payHtml) {
+        this.payHtml = payHtml;
+    }
+}

+ 79 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/RsqMsg.java

@@ -0,0 +1,79 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import java.util.Map;
+
+public class RsqMsg {
+    private String merNo;
+    private String version;
+    private String notifyUrl;
+    private String timestamp;
+    private String apiContent;
+    private String signType;
+    private String sign;
+
+    public RsqMsg(Map<String, Object> payMap) {
+        merNo = (String) payMap.get("merNo");
+        version = (String) payMap.get("version");
+        notifyUrl = (String) payMap.get("notifyUrl");
+        timestamp = (String) payMap.get("timestamp");
+        apiContent = (String) payMap.get("apiContent");
+        signType = (String) payMap.get("signType");
+        sign = (String) payMap.get("sign");
+    }
+
+    public String getMerNo() {
+        return merNo;
+    }
+
+    public void setMerNo(String merNo) {
+        this.merNo = merNo;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public void setTimestamp(String timestamp) {
+        this.timestamp = timestamp;
+    }
+
+    public String getApiContent() {
+        return apiContent;
+    }
+
+    public void setApiContent(String apiContent) {
+        this.apiContent = apiContent;
+    }
+
+    public String getSignType() {
+        return signType;
+    }
+
+    public void setSignType(String signType) {
+        this.signType = signType;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+}

+ 51 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/YqPayFeignService.java

@@ -0,0 +1,51 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import feign.Logger;
+import feign.codec.Encoder;
+import feign.form.spring.SpringFormEncoder;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.cloud.openfeign.support.SpringEncoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.*;
+
+
+import java.util.Map;
+
+@FeignClient(value = "YqPayFeignService",url = "https://qyfquery.95epay.com",configuration = YqPayFeignService.FormSupportConfig.class)
+public interface YqPayFeignService {
+
+    @PostMapping(name = "订单查询", value = "/query/trade/tradeQuery",
+            consumes = {MediaType.APPLICATION_FORM_URLENCODED_VALUE},
+            produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}
+    )
+    Msg orderQuery(RsqMsg rsqMsg);
+
+    @RequestMapping(name = "用户信息查询", value = "/query/account/queryAccount", method = RequestMethod.POST)
+    String queryAccount(@RequestParam Map<String, Object> map);
+
+    @RequestMapping(name = "对账查询", value = "/query/bill/billQuery", method = RequestMethod.POST)
+    String billQuery(@RequestParam Map<String, Object> map);
+
+
+    class FormSupportConfig {
+
+
+        @Autowired
+        private ObjectFactory<HttpMessageConverters> messageConverters;
+        // new一个form编码器,实现支持form表单提交
+        @Bean
+        public Encoder feignFormEncoder() {
+            return new SpringFormEncoder(new SpringEncoder(messageConverters));
+        }
+        // 开启Feign的日志
+        @Bean
+        public Logger.Level logger() {
+            return Logger.Level.FULL;
+        }
+    }
+
+    }

+ 119 - 0
edu-thirdparty/src/main/java/com/keao/edu/thirdparty/yqpay/YqPayUtil.java

@@ -0,0 +1,119 @@
+package com.keao.edu.thirdparty.yqpay;
+
+import com.alibaba.fastjson.JSON;
+
+import java.math.BigDecimal;
+import java.util.*;
+
+public class YqPayUtil {
+
+    private static final String merNo = "0021677"; //商户号
+    private static final String version = "1.1";
+    private static final String signType = "CFCA";
+    private static final String payUrl = "https://qyfapi.95epay.com/api/api/hPay/toPayHtml";//支付提交地址
+    private static final String payChannels = "{\"weChatPay\":true,\"weChatPayMobile\":false,\"aliPay\":true,\"fastpayXy\":true,\"aliPayMobile\":false,\"balancePay\":false}";//支付方式配置
+
+    public static Map<String, Object> getRequestMap(String notifyUrl, Map<String, Object> resultMap) throws Exception {
+        Map<String, Object> rqMap = new LinkedHashMap<>();
+        rqMap.put("merNo", merNo);
+        rqMap.put("version", version);
+        rqMap.put("notifyUrl", notifyUrl);
+        rqMap.put("timestamp", DateUtils.getDateTime());
+        rqMap.put("apiContent", JSON.toJSONString(resultMap));
+        rqMap.put("signType", signType);
+        String beforeSignedData = CFCARAUtil.joinMapValue(rqMap, '&');
+        String sign = CFCARAUtil.signMessageByP1(beforeSignedData, "config/certificate/yqpay.pfx", "aaa123123");
+        rqMap.put("sign", sign);
+        return rqMap;
+    }
+
+    /**
+     * 获取支付Map
+     *
+     * @param amount
+     * @param orderNo
+     * @param notifyUrl
+     * @param returnUrl
+     * @param orderSubject
+     * @param orderBody
+     * @param routingMerNo
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, Object> getPayMap(BigDecimal amount, String orderNo, String notifyUrl, String returnUrl, String orderSubject, String orderBody, String sellerNo, String routingMerNo) throws Exception {
+        List<Map> tempRoutingList = new ArrayList();
+        Map<String, Object> routingList = new HashMap<>();
+        routingList.put("routingMerNo", routingMerNo);//分佣账户
+        routingList.put("routingFee", amount.subtract((amount.multiply(new BigDecimal("0.28")).divide(new BigDecimal(100))).setScale(2, BigDecimal.ROUND_HALF_UP))); //分佣金额
+        tempRoutingList.add(routingList);
+
+        Map<String, Object> contentMap = new LinkedHashMap<>();
+        contentMap.put("sellerNo", sellerNo); //收款商户号
+        contentMap.put("payChannels", payChannels); //支付方式
+        contentMap.put("orderBody", orderBody); //订单信息
+        contentMap.put("payAmount", amount); //支付金额
+        contentMap.put("apiPayType", "1"); //*API支付类型1-即时支付,2-担保支付,3-预授权支付*/
+        contentMap.put("tradeType", "0"); //*交易类型1—充值,0—收款*
+        contentMap.put("merMerOrderNo", orderNo); //商户订单号
+        contentMap.put("orderSubject", orderSubject); //订单标题
+        contentMap.put("returnUrl", returnUrl); //前台页面地址
+        if (routingMerNo != null && !routingMerNo.isEmpty() && !sellerNo.equals(routingMerNo)) {
+            contentMap.put("tempRoutingList", JSON.toJSONString(tempRoutingList));//分账设置
+        }
+        Map<String, Object> payMap = getRequestMap(notifyUrl, contentMap);
+        payMap.put("host", payUrl);
+        return payMap;
+    }
+
+    /**
+     * 获取支付Map
+     *
+     * @param amount
+     * @param orderNo
+     * @param notifyUrl
+     * @param returnUrl
+     * @param orderSubject
+     * @param orderBody
+     * @param sellerNo
+     * @param tempRoutingList
+     * @return
+     * @throws Exception
+     */
+    public static Map<String, Object> getPayMap(BigDecimal amount, String orderNo, String notifyUrl, String returnUrl, String orderSubject, String orderBody, String sellerNo, List<Map<String, Object>> tempRoutingList) throws Exception {
+        Map<String, Object> contentMap = new LinkedHashMap<>();
+        contentMap.put("sellerNo", sellerNo); //收款商户号
+        contentMap.put("payChannels", payChannels); //支付方式
+        contentMap.put("orderBody", orderBody); //订单信息
+        contentMap.put("payAmount", amount); //支付金额
+        contentMap.put("apiPayType", "1"); //*API支付类型1-即时支付,2-担保支付,3-预授权支付*/
+        contentMap.put("tradeType", "0"); //*交易类型1—充值,0—收款*
+        contentMap.put("merMerOrderNo", orderNo); //商户订单号
+        contentMap.put("orderSubject", orderSubject); //订单标题
+        contentMap.put("returnUrl", returnUrl); //前台页面地址
+        if (tempRoutingList != null) {
+            contentMap.put("tempRoutingList", JSON.toJSONString(tempRoutingList));//分账设置
+        }
+        Map<String, Object> payMap = getRequestMap(notifyUrl, contentMap);
+        payMap.put("host", payUrl);
+        return payMap;
+    }
+
+
+    /**
+     * 验签
+     *
+     * @param rsMap
+     * @return
+     */
+    public static boolean verify(Map<String, Object> rsMap) {
+        String sign = (String) rsMap.get("sign");
+        rsMap.remove("sign");
+        String beforeSignedData = CFCARAUtil.joinMapValue(rsMap, '&');
+        try {
+            return CFCARAUtil.verifyMessageByP1(beforeSignedData, sign, "/config/certificate/sq_formal_sign.cer");
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+}