Explorar el Código

联合丽格付款/分账

zhijiezhao hace 2 años
padre
commit
61bb6d2c9b

+ 12 - 1
pom.xml

@@ -21,6 +21,11 @@
     </parent>
 
     <dependencies>
+        <dependency>
+            <groupId>com.squareup.okhttp3</groupId>
+            <artifactId>okhttp</artifactId>
+            <version>3.8.1</version>
+        </dependency>
         <!--spring Boot原始依赖-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
@@ -65,7 +70,13 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.6</version>
+            <version>1.2.76</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.caimei</groupId>
+            <artifactId>caimei-common</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
         </dependency>
 
         <!-- 分页插件 -->

+ 104 - 0
src/main/java/com/caimei/modules/order/constant/Constant.java

@@ -0,0 +1,104 @@
+package com.caimei.modules.order.constant;
+
+
+/**
+ * 常量类
+ *
+ * @author Administrator
+ */
+public class Constant {
+
+    public static final String prodSplit = "https://core.caimei365.com/order/pay/delay/split/callback";
+
+    public static final String betaSplit = "https://core-b.caimei365.com/order/pay/delay/split/callback";
+
+    //快捷支付请求地址
+    public static final String REQUEST_URL_QUICKPAY = "http://quickpay.trx.helipay.com/trx/quickPayApi/interface.action";
+
+    /**
+     * 专票 信息 测试佣金暂入信息  308785626@qq.com vip/二手暂入信息
+     */
+    public static final String CUSTOMERNUM = "E1807059160";
+    /**
+     * 信息的邮箱
+     */
+    public static final String XX_MAIL = "308785626@qq.com";
+
+    /**
+     * 收款商编 网络   xun.zhang@caimei365.com
+     */
+    public static final String CUSTOMERNUM2 = "E1807062884";
+    /**
+     * 网络的邮箱
+     */
+    public static final String WL_MAIL = "xun.zhang@caimei365.com";
+    /**
+     * 普票 奥泰 测试私账暂进奥泰   caimei365@yeah.net
+     */
+    public static final String CUSTOMERNUM3 = "E1807085606";
+
+    public static final String AT_MAIL = "caimei365@yeah.net";
+
+    public static final String SPLIT = "&";
+
+    public static final String DOMAIN_NAME = "http://pay.trx.helipay.com/";
+    /**
+     * 网银地址http://pay.trx.helipay.com/trx/online/interface.action
+     */
+    public static final String YL = "http://pay.trx.helipay.com/trx/online/interface.action";
+    /**
+     * 分账地址
+     */
+    public static final String FZ = "http://pay.trx.helipay.com/trx/accountPay/interface.action";
+    /**
+     * 结算地址
+     */
+    public static final String JS = "http://transfer.trx.helipay.com/trx/transfer/interface.action";
+
+    /**
+     * 微信/支付宝扫码/小程序公众号支付
+     */
+    public static final String SAOMA = "1iHnZaalUNAVcfcbKdh6n86Z0yUHtM6f";
+    /**
+     * 网银
+     */
+    public static final String WANGYIN = "CZiCbGrgFYQMldVkQnzbFQeQkn6mp25w";
+    /**
+     * 虚拟账户支付
+     */
+    public static final String XUNI = "8VmdRSXMIOfUo7aEq1iYs2XEWgGZpBQc";
+    /**
+     * 分账
+     */
+    public static final String FENZHANG = "2hATS0A4IoxdudGxNkGRNOt6aFSdOd8Q";
+    /**
+     * 公共产品
+     */
+    public static final String GONG="wrED4jYgKLQVsEwtgZ2eQmXrRgo7VHy4";
+    /**
+     * 结算
+     */
+    public static final String JIESUAN="fiweQU8igfuhBTcXLLDAQ3DScwIPEy2s";
+
+    /**
+     * 扫码接口地址
+     */
+    public static final String REQUEST_URL = DOMAIN_NAME + "trx/app/interface.action";
+    /**
+     *     结算私钥
+     */
+    public static final String signKey_setttlement = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK8T2luDwK3jKwLp\n" +
+            "AVNRr8+1qHGUkCIe6ZicK6Oc33xB4vA+2Hyz9I9343DgcYbuq6/t7lxzb5+fRvjd\n" +
+            "B63YM4bFDh0nyDeoNwoKCWUlHV1iuqJC5rHr/C96IR+l0Aiu619lZI+mmkFgX8xd\n" +
+            "g2gX4Up1sqZlwy0qv25mm9skyK01AgMBAAECgYEAn75YjQmhA8fzlbsuF2zAIqAY\n" +
+            "alHoVQmpkDJmaumWzJR9UUG2W8oCiekU4AgZ7cjVZDePNlGpdpZotmdOO2O6VmkF\n" +
+            "x9mOcgcM87t9PmkkRcVjpvkSixFyNFRpcYECm+YXOE/d/1rS5zvOubU3L8XzvP9O\n" +
+            "SQQhQ8xtVl9SFoAMB70CQQDkQv7mtsoMrwqxwC4/tXzSoOclEOSWXqtNEAxMlq5D\n" +
+            "ZAPeOSfImwTlb7s5lX1MkrbdOvf2EWoW5cNaLyIdo3jDAkEAxFpZUvUu0oS4EOtX\n" +
+            "kXZaJicuRaovY9TzGjEr9pTgRGlOcK3pUS4nNEKqT8cBfgNJ1veBsk25g8fHMKQq\n" +
+            "GMkipwJBAMl0+6XCM+cn4gdpNyhRVD5NdlO3ahfwq71S6Zf68QhXUDakOSGK97JL\n" +
+            "f3FeJ30ai7wLXGdXjUtyM4z3xmNkMKMCQFC5ECXx1JkJpR6Xkj2kGXW7/+L2D1uM\n" +
+            "jZEEDB3ooLafUHc0mEoenlF24su/ddaXhYDR6kkieRU7SaGuq/vanNsCQQC8fuH0\n" +
+            "APa0grLrsMdNTLlHNCnf/s+mjeMt3rV3SbPZ5pbnEPWILYvxN8NnOVZmxQw6E7+R\n" +
+            "CBcHmGCo7zF53o4t";
+}

+ 25 - 2
src/main/java/com/caimei/modules/order/controller/OrderPayShopController.java

@@ -14,6 +14,9 @@ import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
+import java.util.List;
+
 /**
  * @author zzj
  */
@@ -70,14 +73,34 @@ public class OrderPayShopController {
         return payShopService.checkPass(id, payType, passCode);
     }
 
-    @ApiOperation("付款申请")
+    @ApiOperation("付款申请/重申付款")
     @ApiImplicitParams({
-            @ApiImplicitParam(required = true, name = "id", value = "付款单Id")
+            @ApiImplicitParam(required = false, name = "payShopId", value = "付款单Id"),
+            @ApiImplicitParam(required = true, name = "name", value = "付款单名称"),
+            @ApiImplicitParam(required = true, name = "bankAccount", value = "付款帐号"),
+            @ApiImplicitParam(required = true, name = "bankName", value = "付款帐号的开户行"),
+            @ApiImplicitParam(required = true, name = "bankAccountName", value = "户名"),
+            @ApiImplicitParam(required = true, name = "cmBankAccount", value = "付采美帐号"),
+            @ApiImplicitParam(required = true, name = "cmBankName", value = "付采美账号的开户行"),
+            @ApiImplicitParam(required = true, name = "cmBankAccountName", value = "付采美账号的户名"),
+            @ApiImplicitParam(required = true, name = "type", value = "付款账号的类型 0公账, 1私账")
     })
     @PostMapping("/pay/apply")
     public ResponseJson applyPay(OrderPayShopDetail payShop) throws Exception {
         return payShopService.applyPay(payShop);
     }
 
+    @ApiOperation("取消付款单")
+    @ApiImplicitParam(required = true, name = "id", value = "付款单Id")
+    @GetMapping("/pay/cancel/{id}/{status}")
+    public ResponseJson cancelPay(@PathVariable("id") Integer id) {
+        return payShopService.cancelPay(id);
+    }
 
+    @ApiOperation("申请分账")
+    @ApiImplicitParam(name = "shopOrderIds", value = "子订单IdList", required = true, allowMultiple=true, dataType="int", paramType = "query")
+    @GetMapping("/pay/cancel")
+    public ResponseJson splitShopOrders(List<Integer> shopOrderIds) {
+        return payShopService.splitShopOrders(shopOrderIds);
+    }
 }

+ 21 - 1
src/main/java/com/caimei/modules/order/dao/NewOrderDao.java

@@ -1,6 +1,6 @@
 package com.caimei.modules.order.dao;
 
-import com.caimei.modules.order.entity.NewOrder;
+import com.caimei.modules.order.entity.*;
 import org.apache.ibatis.annotations.Mapper;
 
 import java.util.List;
@@ -15,4 +15,24 @@ public interface NewOrderDao {
     void update(NewOrder order);
 
     void updatePayStatus(Integer status, Integer orderId);
+
+    List<CmReceiptOrderRelation> getUndividedPaidReceipt(String currentTime, Integer shopOrderId);
+
+    NewShopOrder getShopOrderListByOrderId(Integer shopOrderId);
+
+    void insertSplitAccount(SplitAccountPo splitAccountPo);
+
+    List<SplitAccountPo> getSplitAccountList(String mbOrderId);
+
+    List<NewShopOrder> getShopOrderByOrderId(Integer orderId);
+
+    Double getPaidShopAmount(Integer shopOrderId);
+
+    void updateShopOrderByPayStatus(Integer shopOrderId, Double paidShop, Integer payStatus);
+
+    void updateBySplitStatus(String mbOrderId);
+
+    List<NewOrderProduct> getOrderProductByShopOrderId(Integer shopOrderId);
+
+    Double getOrderProductPaidAmount(Integer orderProductId);
 }

+ 8 - 0
src/main/java/com/caimei/modules/order/dao/PayShopDao.java

@@ -34,4 +34,12 @@ public interface PayShopDao {
     void insertPayRecord(OrderPayShopRecord record);
 
     void updatePaying(Integer shopOrderId);
+
+    void updatePayShopDetail(OrderPayShopDetail payShop);
+
+    void updateRecordById(Integer shopOrderId, Double waitPayShop, Double waitPayCmAmount, Integer payShopId);
+
+    void updateShopAccount(Integer shopId, String bankAccount, String bankAccountName, String bankName);
+
+    void deleteRecords(Integer id);
 }

+ 197 - 0
src/main/java/com/caimei/modules/order/entity/AccountPayOrder.java

@@ -0,0 +1,197 @@
+package com.caimei.modules.order.entity;
+
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Set;
+
+public class AccountPayOrder {
+
+    private String P1_bizType;
+    private String P2_signType;
+    private String P3_timestamp;
+    private String P4_orderId;
+    private String P5_customerNumber;
+    private String P6_ext;
+
+    public String getP1_bizType() {
+        return P1_bizType;
+    }
+
+    public void setP1_bizType(String p1_bizType) {
+        P1_bizType = p1_bizType;
+    }
+
+    public String getP2_signType() {
+        return P2_signType;
+    }
+
+    public void setP2_signType(String p2_signType) {
+        P2_signType = p2_signType;
+    }
+
+    public String getP3_timestamp() {
+        return P3_timestamp;
+    }
+
+    public void setP3_timestamp(String p3_timestamp) {
+        P3_timestamp = p3_timestamp;
+    }
+
+    public String getP4_orderId() {
+        return P4_orderId;
+    }
+
+    public void setP4_orderId(String p4_orderId) {
+        P4_orderId = p4_orderId;
+    }
+
+    public String getP5_customerNumber() {
+        return P5_customerNumber;
+    }
+
+    public void setP5_customerNumber(String p5_customerNumber) {
+        P5_customerNumber = p5_customerNumber;
+    }
+
+
+    public String getP6_ext() {
+        return P6_ext;
+    }
+
+    public void setP6_ext(String p6_ext) {
+        P6_ext = p6_ext;
+    }
+
+    public static class AccountPayOrderExt {
+        // 订单类型
+        private AccountPayOrderType orderType;
+        // 收款商编
+        private String inMerchantNo;
+        // 金额
+        private BigDecimal amount;
+        // 回调地址
+        private String serverCallbackUrl;
+        // 商品名称
+        private String goodsName;
+        // 商品描述(可选)
+        private String orderDesc;
+        /**
+         * 以下两项在补贴场景下必填
+         **/
+        private ProductType productType;
+        // 原收单订单号
+        private String associatedOrderNo;
+        // 分账规则串 - 仅支持资金划拨类订单
+        private List<SplitBillRule> splitBillRules;
+        // 是否为担保交易
+        private boolean inEscrow = false;
+
+
+        public AccountPayOrderType getOrderType() {
+            return orderType;
+        }
+
+        public void setOrderType(AccountPayOrderType orderType) {
+            this.orderType = orderType;
+        }
+
+        public BigDecimal getAmount() {
+            return amount;
+        }
+
+        public void setAmount(BigDecimal amount) {
+            this.amount = amount;
+        }
+
+        public String getServerCallbackUrl() {
+            return serverCallbackUrl;
+        }
+
+        public void setServerCallbackUrl(String serverCallbackUrl) {
+            this.serverCallbackUrl = StringUtils.isEmpty(serverCallbackUrl) ? null : serverCallbackUrl;
+        }
+
+        public String getGoodsName() {
+            return goodsName;
+        }
+
+        public void setGoodsName(String goodsName) {
+            this.goodsName = goodsName;
+        }
+
+        public String getOrderDesc() {
+            return orderDesc;
+        }
+
+        public void setOrderDesc(String orderDesc) {
+            this.orderDesc = orderDesc;
+        }
+
+        public ProductType getProductType() {
+            return productType;
+        }
+
+        public void setProductType(ProductType productType) {
+            this.productType = productType;
+        }
+
+        public String getAssociatedOrderNo() {
+            return associatedOrderNo;
+        }
+
+        public void setAssociatedOrderNo(String associatedOrderNo) {
+            this.associatedOrderNo = associatedOrderNo;
+        }
+
+        public String getInMerchantNo() {
+            return inMerchantNo;
+        }
+
+        public void setInMerchantNo(String inMerchantNo) {
+            this.inMerchantNo = inMerchantNo;
+        }
+
+        public List<SplitBillRule> getSplitBillRules() {
+            return splitBillRules;
+        }
+
+        public void setSplitBillRules(List<SplitBillRule> splitBillRules) {
+            this.splitBillRules = splitBillRules;
+        }
+
+        public boolean isInEscrow() {
+            return inEscrow;
+        }
+
+        public void setInEscrow(boolean inEscrow) {
+            this.inEscrow = inEscrow;
+        }
+
+        public static class SplitBillRule {
+            private String splitBillMerchantNo; // 收账商编
+            private BigDecimal splitBillAmount; // 分账金额
+
+            public String getSplitBillMerchantNo() {
+                return splitBillMerchantNo;
+            }
+
+            public void setSplitBillMerchantNo(String splitBillMerchantNo) {
+                this.splitBillMerchantNo = splitBillMerchantNo;
+            }
+
+            public BigDecimal getSplitBillAmount() {
+                return splitBillAmount;
+            }
+
+            public void setSplitBillAmount(BigDecimal splitBillAmount) {
+                this.splitBillAmount = splitBillAmount;
+            }
+        }
+
+
+    }
+
+}

+ 28 - 0
src/main/java/com/caimei/modules/order/entity/AccountPayOrderType.java

@@ -0,0 +1,28 @@
+package com.caimei.modules.order.entity;
+
+public enum AccountPayOrderType {
+
+    ALLOWANCE("活动补贴", 1),
+
+    TRANSFER("资金划拨", 2),
+
+
+    ;
+
+    private final String desc;
+    private final Integer index;
+
+
+    AccountPayOrderType(String desc, Integer index) {
+        this.desc = desc;
+        this.index = index;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public Integer getIndex() {
+        return index;
+    }
+}

+ 30 - 7
src/main/java/com/caimei/modules/order/entity/CmReceiptOrderRelation.java

@@ -17,23 +17,23 @@ public class CmReceiptOrderRelation implements Serializable {
     /**
      *  关系类型:1返佣订单(返佣款)、2非返佣订单(订单款或者非订单款)
      */
-    private String relationType;
+    private Integer relationType;
     /**
      * 识别款项Id(对应cm_discern_receipt表)
      */
-    private String receiptId;
+    private Integer receiptId;
     /**
      * 关联金额:1普通收款(线下):收款具体对该应母订单的收金额、2线上支付:付款金额就等于该金额、3返佣收款:默认为0
      */
-    private String associateAmount;
+    private Double associateAmount;
     /**
      * 订单Id(relationType值为1是为子订单ID,为2时为主订单ID)
      */
-    private String orderId;
+    private Integer orderId;
     /**
      * 收款类型
      */
-    private String payType;
+    private Integer payType;
     /**
      * 收款时间
      */
@@ -41,6 +41,29 @@ public class CmReceiptOrderRelation implements Serializable {
     /**
      * 确认订单类型
      */
-    private String confirmType;
-
+    private Integer confirmType;
+    /**
+     * 关联方式: 1手动 2自动
+     */
+    private Integer associationType;
+    /**
+     * 子订单id
+     */
+    private Integer shopOrderId;
+    /**
+     * 删除标记 0 否,其余是
+     */
+    private Integer delFlag;
+    /**
+     * 米花科技平台唯一流水号
+     */
+    private String mbOrderId;
+    /**
+     * 商户唯一订单请求号(订单编号#随机时间戳)
+     */
+    private String orderRequestNo;
+    /**
+     * 分账状态:0待分账,1已分账(只针对线上支付)
+     */
+    private Integer splitStatus;
 }

+ 8 - 0
src/main/java/com/caimei/modules/order/entity/NewOrderProduct.java

@@ -112,4 +112,12 @@ public class NewOrderProduct {
     @ApiModelProperty("单个付供应商税费")
     private Double singleShouldPayTotalTax;
 
+    @ApiModelProperty("付采美佣金比例")
+    private Integer cmPercent;
+    @ApiModelProperty("付组织佣金比例")
+    private Integer organizePercent;
+    @ApiModelProperty("付组织供应商佣金比例")
+    private Integer shopPercent;
+    @ApiModelProperty("分帐号")
+    private String splitCode;
 }

+ 14 - 6
src/main/java/com/caimei/modules/order/entity/OrderPayShopDetail.java

@@ -17,6 +17,20 @@ public class OrderPayShopDetail implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
+    @ApiModelProperty("供应商付款账号的户名")
+    private String bankAccountName;
+    @ApiModelProperty("供应商付款账号")
+    private String bankAccount;
+    @ApiModelProperty("供应商付款账号的开户行")
+    private String bankName;
+
+    @ApiModelProperty("付采美账号的户名")
+    private String cmBankAccountName;
+    @ApiModelProperty("付采美账号")
+    private String cmBankAccount;
+    @ApiModelProperty("付采美账号的开户行")
+    private String cmBankName;
+
     @ApiModelProperty("shopId")
     private Integer shopId;
     @ApiModelProperty("付款单Id")
@@ -25,12 +39,6 @@ public class OrderPayShopDetail implements Serializable {
     private String name;
     @ApiModelProperty("供应商名称")
     private String shopName;
-    @ApiModelProperty("付款账号的户名")
-    private String bankAccountName;
-    @ApiModelProperty("付款账号")
-    private String bankAccount;
-    @ApiModelProperty("付款账号的开户行")
-    private String bankName;
     @ApiModelProperty("付供应商总金额")
     private Double totalAmount;
     @ApiModelProperty("付款银行")

+ 99 - 0
src/main/java/com/caimei/modules/order/entity/PayParamBo.java

@@ -0,0 +1,99 @@
+package com.caimei.modules.order.entity;
+
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Description
+ */
+@Data
+public class PayParamBo implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * 用户Id
+     */
+    private Integer userId;
+    /**
+     * 订单Id
+     */
+    private Integer orderId;
+    /**
+     * 二手发布商品id
+     */
+    private Integer productId;
+    /**
+     * 会员购买记录Id
+     */
+    private Integer vipRecordId;
+    /**
+     * 优惠券购买记录id
+     */
+    private Integer couponRecordId;
+    /**
+     * 会员套餐id
+     */
+    private Integer vipId;
+    /**
+     * 支付金额,单位分,必须大于2
+     */
+    private Integer payAmount;
+    /**
+     * double支付金额,单位元
+     */
+    private Double AllPay;
+    /**
+     * 支付方式,
+     * 银联:UNIONPAY,
+     * 微信:WEIXIN,
+     * 支付宝:ALIPAY,
+     * 银联转账:TRANSFER
+     */
+    private String payWay;
+    /**
+     * 支付类型(现阶段主要是区分微信支付)
+     * 微信小程序支付: MINIAPP_WEIXIN
+     * 微信公众号支付: JSAPI_WEIXIN
+     */
+    private String payType;
+    /**
+     * 微信小程序code,微信小程序支付使用
+     */
+    private String code;
+    /**
+     * 微信公众号state参数
+     */
+    private String state;
+    /**
+     * 页面回调地址
+     */
+    private String returnUrl;
+    /**
+     * 微信openId
+     */
+    private String openId;
+    /**
+     * 异步通知回调
+     */
+    private String notifyUrl;
+    /**
+     * 银行编码(银联支付使用)
+     */
+    private String bankCode;
+    /**
+     * 用户类型(银联支付使用)
+     * 企业:ENTERPRISE
+     * 个人:USER
+     */
+    private String userType;
+    /**
+     * 购买优惠券id
+     */
+    private Integer couponId;
+    /**
+     *  1小程序 2网站
+     */
+    private Integer source;
+}

+ 78 - 0
src/main/java/com/caimei/modules/order/entity/SplitAccountPo.java

@@ -0,0 +1,78 @@
+package com.caimei.modules.order.entity;
+
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class SplitAccountPo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+    /**
+     * 主订单id
+     */
+    private Integer orderId;
+    /**
+     * 子订单Id
+     */
+    private Integer shopOrderId;
+    /**
+     * 商品id,仅对二手发布商品
+     */
+    private Integer productId;
+    /**
+     * 订单商品id
+     */
+    private Integer orderProductId;
+    /**
+     * 供应商id
+     */
+    private Integer shopId;
+    /**
+     * 超级会员套餐id
+     */
+    private Integer vipRecordId;
+    /**
+     * 优惠券购买记录id
+     */
+    private Integer couponRecordId;
+    /**
+     * 认证通会员购买记录id
+     */
+    private Integer authVipRecordId;
+    /**
+     * 分账类型:1公账-专票,2私账-无票,3公账-普票,4供应商子商户,5佣金账户
+     */
+    private Integer type;
+    /**
+     * 子商户商编
+     */
+    private String subUserNo;
+    /**
+     * 分账金额
+     */
+    private Double splitAccount;
+    /**
+     * 米花科技平台唯一流水号
+     */
+    private String mbOrderId;
+    /**
+     * 商户唯一订单请求号(订单编号#随机时间戳)
+     */
+    private String orderRequestNo;
+    /**
+     * 付款状态,0待付,1付款成功
+     */
+    private Integer payStatus;
+    /**
+     * 商品类型:1商品成本,2供应商运费,3佣金,4二手发布
+     */
+    private Integer productType;
+    /**
+     * 分账时间
+     */
+    private Date splitTime;
+}

+ 6 - 0
src/main/java/com/caimei/modules/order/service/PayShopService.java

@@ -5,6 +5,8 @@ import com.caimei.modules.order.entity.OrderPayShopDetail;
 import com.caimei.utils.ResponseJson;
 import com.github.pagehelper.PageInfo;
 
+import java.util.List;
+
 /**
  * @author zzj
  */
@@ -17,4 +19,8 @@ public interface PayShopService {
     ResponseJson checkPass(Integer id, Integer payType, Integer passCode) throws Exception;
 
     ResponseJson applyPay(OrderPayShopDetail payShop) throws Exception;
+
+    ResponseJson cancelPay(Integer id);
+
+    ResponseJson splitShopOrders(List<Integer> shopOrderIds);
 }

+ 415 - 40
src/main/java/com/caimei/modules/order/service/impl/PayShopServiceImpl.java

@@ -1,27 +1,39 @@
 package com.caimei.modules.order.service.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.caimei.modules.order.constant.Constant;
 import com.caimei.modules.order.dao.NewOrderDao;
 import com.caimei.modules.order.dao.NewShopOrderDao;
 import com.caimei.modules.order.dao.PayShopDao;
 import com.caimei.modules.order.entity.*;
 import com.caimei.modules.order.service.PayShopService;
 import com.caimei.modules.shiro.entity.CmMallAdminUser;
+import com.caimei.po.OrderProductV;
 import com.caimei.utils.DateUtils;
+import com.caimei.utils.Disguiser;
 import com.caimei.utils.MathUtil;
 import com.caimei.utils.ResponseJson;
 import com.github.pagehelper.PageHelper;
 import com.github.pagehelper.PageInfo;
-import com.github.pagehelper.util.StringUtil;
+import com.google.common.util.concurrent.AtomicDouble;
 import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
 import org.apache.shiro.SecurityUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
+import java.io.IOException;
+import java.lang.reflect.Field;
 import java.math.BigDecimal;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
+import java.math.RoundingMode;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import com.caimei.redis.RedisService;
 
 /**
  * @author zzj
@@ -30,6 +42,14 @@ import java.util.List;
 @Service
 public class PayShopServiceImpl implements PayShopService {
 
+    public static OkHttpClient client = new OkHttpClient.Builder()
+            .connectTimeout(3, TimeUnit.SECONDS)
+            .readTimeout(20, TimeUnit.SECONDS)
+            .build();
+
+
+    @Resource
+    private RedisService redisService;
     @Resource
     private PayShopDao payShopDao;
     @Resource
@@ -123,18 +143,14 @@ public class PayShopServiceImpl implements PayShopService {
     public ResponseJson applyPay(OrderPayShopDetail payShop) throws Exception {
         CmMallAdminUser user = (CmMallAdminUser) SecurityUtils.getSubject().getPrincipal();
         payShop.setApplicant(user.getId());
+        List<NewShopOrder> shopOrders = payShop.getShopOrders();
         if (null == payShop.getPayShopId()) {
             //新增
-
             payShop.setApplyTime(DateUtils.getDateTime());
             payShop.setStatus(0);
             payShopDao.insertPayShop(payShop);
-            //保存每个子订单的付款金额记录  等待审核付款
-            shop.setBankAccount(payShop.getBankAccount());
-            shop.setBankAccountName(payShop.getBankAccountName());
-            shop.setBankName(payShop.getBankName());
-            payShopDao.update(shop);
-            List<NewShopOrder> shopOrders = payShop.getShopOrders();
+
+            payShopDao.updateShopAccount(payShop.getShopId(), payShop.getBankAccount(), payShop.getBankAccountName(), payShop.getBankName());
             shopOrders.forEach(s -> {
                 OrderPayShopRecord record = new OrderPayShopRecord();
                 record.setShopId(payShop.getShopId());
@@ -153,12 +169,10 @@ public class PayShopServiceImpl implements PayShopService {
 
         } else {
             //修改
-            if (StringUtil.isNoneEmpty(payShop.getReApply())) {
-                //查询订单的paying
-                Integer count = newShopOrderDao.getPayingStatus(payShop.getPayShopId());
-                if (count > 0) {
-                    throw new Exception("订单已经处于付款状态");
-                }
+            if (1 == payShop.getStatus()) {
+                throw new Exception("该付款单已被审核,无需再申请付款");
+            }
+            if (2 == payShop.getStatus()) {
                 //付款记录 修改状态
                 payShopDao.updatePayRecordById(2, payShop.getPayShopId());
                 //子订单退出付款状态
@@ -167,36 +181,397 @@ public class PayShopServiceImpl implements PayShopService {
                 payShop.setReviewTime(null);
                 payShop.setReason(null);
                 payShop.setStatus(0);
-            } else {
-                if (1 == payShop.getStatus()) {
-                    throw new Exception("该付款单已被审核,无需再申请付款");
-                }
-                if (2 == payShop.getStatus()) {
-                    //付款记录 修改状态
-                    payShopDao.updatePayRecordById(2, payShop.getPayShopId());
-                    //子订单退出付款状态
-                    newShopOrderDao.inPaying(payShop.getPayShopId());
-                    payShop.setReviewer(null);
-                    payShop.setReviewTime(null);
-                    payShop.setReason(null);
-                    payShop.setStatus(0);
-                }
+            }
+            shopOrders.forEach(s -> {
+                payShopDao.updateRecordById(s.getShopOrderId(), s.getWaitPayShop(), s.getWaitPayCmAmount(), payShop.getPayShopId());
+            });
+            payShopDao.updatePayShopDetail(payShop);
+        }
+        return ResponseJson.success("申请成功");
+    }
 
-                CmPayShop dbBean = cmPayShopDao.get(payShop.getPayShopId());
-                NewCmShop shop = newCmShopDao.get(payShop.getShopId());
+    @Transactional(readOnly = false)
+    @Override
+    public ResponseJson cancelPay(Integer id) {
+        OrderPayShopDetail payShopDetail = payShopDao.findPayShopDetail(id);
+        if (1 == payShopDetail.getStatus()) {
+            return ResponseJson.error("该付款单已被审核,不能取消");
+        }
+        newShopOrderDao.outPaying(id);
+        payShopDao.deleteRecords(id);
+        return ResponseJson.success();
+    }
 
-                for (String p : payInfo) {
-                    String shopOrderID = p.split("_")[0];
-                    Double payAmount = Double.valueOf(p.split("_")[1]);
-                    Double wipeFee = Double.valueOf(p.split("_")[2]);
-                    cmPayShopRecordDao.updateByID(payShop.getPayShopId(), shopOrderID, payAmount, wipeFee);
+    @Override
+    public ResponseJson splitShopOrders(List<Integer> shopOrderIds) {
+        Integer xsfzmds = (Integer) redisService.get("XSFZMDS");
+        //验锁
+        if (null != xsfzmds && xsfzmds > 0) {
+            return ResponseJson.error("请勿短时间内重复分账,等待支付公司返回分账结果!");
+        }
+        log.info("【手动分账开始】>>>>>>>>>>手动分账");
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(new Date());
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        String currentTime = format.format(calendar.getTime());
+        shopOrderIds.forEach(s -> {
+            // 查询未分账已支付收款
+            List<CmReceiptOrderRelation> orderRelations = newOrderDao.getUndividedPaidReceipt(currentTime, s);
+            if (null != orderRelations && orderRelations.size() > 0) {
+                for (CmReceiptOrderRelation orderRelation : orderRelations) {
+                    log.info("【分账】>>>>>>>>>>子订单id:" + s + "进入分账");
+                    // 收款对应的订单信息
+                    NewShopOrder shopOrder = newOrderDao.getShopOrderListByOrderId(orderRelation.getShopOrderId());
+                    PayParamBo payParam = new PayParamBo();
+                    //支付金额
+                    payParam.setAllPay(orderRelation.getAssociateAmount());
+                    List<SplitAccountPo> splitBillDetail = new ArrayList<>();
+                    /**
+                     *  todo
+                     *  供应商承担手续费,在计算过程中无需处理,按正常比例分配分组织佣金和分采美佣金,
+                     *  佣金分配完成后剩余金额则为供应商成本分账金额 - 供应商承担手续费,不在cm_split_account中做成本扣减体现
+                     *  后续有对账需求再做处理
+                     */
+                    setSplitAccountDetail(shopOrder, payParam, splitBillDetail);
+                    HashMap<String, BigDecimal> sbm = new HashMap<>();
+                    for (SplitAccountPo splitAccountPo : splitBillDetail) {
+                        String subUserNo = splitAccountPo.getSubUserNo();
+                        // 计算当前商户号总分账金额
+                        if (sbm.containsKey(subUserNo)) {
+                            BigDecimal v = MathUtil.add(sbm.get(subUserNo), splitAccountPo.getSplitAccount());
+                            sbm.put(subUserNo, v);
+                        } else {
+                            sbm.put(subUserNo, BigDecimal.valueOf(splitAccountPo.getSplitAccount()));
+                        }
+                        // splitcode相同的收款的时候已经是成本已分帐
+                        if (subUserNo.equals(shopOrder.getSplitCode())) {
+                            splitAccountPo.setMbOrderId(orderRelation.getMbOrderId());
+                            splitAccountPo.setOrderRequestNo(orderRelation.getOrderRequestNo());
+                            // 供应商自己收款,此部分金额留在自己商户号,作为成本分账
+                            splitAccountPo.setPayStatus(1);
+                            // 保存分账详情
+                            newOrderDao.insertSplitAccount(splitAccountPo);
+                        }
+                    }
+                    ArrayList<AccountPayOrder.AccountPayOrderExt.SplitBillRule> splitBillRules = new ArrayList<>();
+                    sbm.forEach((key, value) -> {
+                        /**
+                         *   不是自己的splitcode分走,是自己的不动
+                         *   把成本之外的金额加入splitRule分账参数,延续上面逻辑,供应商自己的成本由自己的商户号收款,
+                         *   自己成本部分不需要加入分账参数,仅需在else中做业务表参数处理
+                         */
+                        if (!key.equals(shopOrder.getSplitCode())) {
+                            AccountPayOrder.AccountPayOrderExt.SplitBillRule splitBillRule = new AccountPayOrder.AccountPayOrderExt.SplitBillRule();
+                            /**
+                             *  由于供应商承担付款手续费,只用参与真实分账部分处理0.1%分账手续费,
+                             *  不在setSplitAccountDetail计算过程中扣除分账手续费
+                             */
+                            BigDecimal bigDecimal = MathUtil.div(value, 1.001).setScale(2, RoundingMode.HALF_UP);
+                            splitBillRule.setSplitBillAmount(bigDecimal);
+                            splitBillRule.setSplitBillMerchantNo(key);
+                            splitBillRules.add(splitBillRule);
+                        } else {
+                            // 成本分账处理
+                            // 子订单的splitcode和分账对象的splitcode一样的是留在账户里的钱,实际在付款完成后,付款状态就为已付款,分账状态就为已分账
+                            // 为维持业务完整性,保持原来的分账流程不变
+                            List<SplitAccountPo> splitAccountList = newOrderDao.getSplitAccountList(orderRelation.getMbOrderId());
+                            if (splitAccountList != null && splitAccountList.size() > 0) {
+                                Integer orderId = splitAccountList.get(0).getOrderId();
+                                List<NewShopOrder> shopOrderList = newOrderDao.getShopOrderByOrderId(orderId);
+                                Integer shopOrderId = null;
+                                String shopOrderNo = "";
+                                for (SplitAccountPo account : splitAccountList) {
+                                    // 本次付供应商金额(分账金额)
+                                    Double splitAmount = account.getSplitAccount();
+                                    orderId = account.getOrderId();
+                                    Integer shopId = account.getShopId();
+                                    for (NewShopOrder shop : shopOrderList) {
+                                        if (shopId.equals(shop.getShopId())) {
+                                            shopOrderId = shop.getShopOrderId();
+                                            shopOrderNo = shop.getShopOrderNo();
+                                            // 已付供应商金额
+                                            Double paidAmount = newOrderDao.getPaidShopAmount(shopOrderId);
+                                            Double paidShop = MathUtil.add(paidAmount, splitAmount).doubleValue();
+                                            shopOrder.setPayedShopAmount(paidShop);
+                                            if (MathUtil.compare(shopOrder.getShouldPayShopAmount(), paidShop) == 0) {
+                                                shopOrder.setPayStatus(3);
+                                            } else {
+                                                shopOrder.setPayStatus(2);
+                                            }
+                                            // 修改子订单付款状态及付款金额
+                                            newOrderDao.updateShopOrderByPayStatus(shopOrderId, paidShop, shopOrder.getPayStatus());
+                                        }
+                                    }
+                                    SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                                    String currentTime2 = format2.format(new Date());
+                                    // 保存付款单表
+                                    OrderPayShopDetail payShop = new OrderPayShopDetail();
+                                    payShop.setShopId(shopId);
+                                    payShop.setName("线上支付分账");
+                                    payShop.setTotalAmount(splitAmount);
+                                    payShop.setPayType(6);
+                                    payShop.setStatus(1);
+                                    payShop.setApplyTime(currentTime2);
+                                    payShop.setReviewTime(currentTime2);
+                                    payShop.setPayTime(currentTime2);
+                                    payShopDao.insertPayShop(payShop);
+                                    // 保存 付供应商记录
+                                    OrderPayShopRecord shopRecord = new OrderPayShopRecord();
+                                    shopRecord.setShopId(shopId);
+                                    shopRecord.setShopOrderId(shopOrderId);
+                                    shopRecord.setShopOrderNo(shopOrderNo);
+                                    shopRecord.setPayAmount(splitAmount);
+                                    shopRecord.setPayType(6);
+                                    shopRecord.setPayTime(new Date());
+                                    shopRecord.setPayShopId(payShop.getPayShopId());
+                                    shopRecord.setStatus(1);
+                                    payShopDao.insertPayRecord(shopRecord);
+                                }
+                                // 子订单是否全部付款
+                                Integer count = newShopOrderDao.findUnPaidShopOrder(orderRelation.getOrderId());
+                                // 修改主订单付款状态
+                                Integer status = count > 0 ? 2 : 3;
+                                newOrderDao.updatePayStatus(status, shopOrder.getOrderId());
+                            }
+                        }
+                    });
+                    /**
+                     *  在上述else代码逻辑中已完成成本的业务表参数处理,在分账详情中排除成本,剩余佣金部分在分账结束收到
+                     *  成功返回码时处理(成本不参与分账)
+                     */
+                    splitBillDetail.removeIf(sp -> sp.getSubUserNo().equals(shopOrder.getSplitCode()));
+                    if (null != splitBillRules && splitBillRules.size() > 0) {
+                        //第三方分账接口
+                        try {
+                            AccountPayOrder accountPayOrder = new AccountPayOrder();
+                            accountPayOrder.setP1_bizType("AccountPaySub");
+                            accountPayOrder.setP2_signType("MD5");
+                            String format1 = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS").format(new Date());
+                            accountPayOrder.setP3_timestamp(format1);
+                            String substring = format1.substring(20);
+                            // fz+当前微秒时间+原唯一订单号
+                            accountPayOrder.setP4_orderId("FZ" + substring + orderRelation.getOrderRequestNo());
+                            //付款账户子订单绑定商户号
+                            accountPayOrder.setP5_customerNumber(shopOrder.getSplitCode());
+                            AccountPayOrder.AccountPayOrderExt accountPayOrderExt = new AccountPayOrder.AccountPayOrderExt();
+                            //收款账户商编  填写splitBillRules时候不填写MerchantNo,Amount并且即使填写这两个参数不生效!!
+                            //accountPayOrderExt.setInMerchantNo(splitMoneyVo.getName());
+                            //accountPayOrderExt.setAmount(splitMoneyVo.getSplitMoney());
+                            accountPayOrderExt.setOrderType(AccountPayOrderType.TRANSFER);
+                            accountPayOrderExt.setServerCallbackUrl(Constant.prodSplit);
+                            accountPayOrderExt.setGoodsName("分账");
+                            if (null != splitBillRules && splitBillRules.size() > 0) {
+                                accountPayOrderExt.setSplitBillRules(splitBillRules);
+                            }
+                            String ext = JSON.toJSONString(accountPayOrderExt);
+                            log.info("分账规则串json串:" + ext);
+                            accountPayOrder.setP6_ext(ext);
+                            // 生成签名
+                            StringBuilder builder = new StringBuilder();
+                            builder.append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP1_bizType()).append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP2_signType()).append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP3_timestamp()).append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP4_orderId()).append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP5_customerNumber()).append(Constant.SPLIT)
+                                    .append(accountPayOrder.getP6_ext()).append(Constant.SPLIT)
+                                    .append(Constant.XUNI);
+                            String sign = Disguiser.disguiseMD5(builder.toString().trim());
+                            Map<String, String> bean = convertBean(accountPayOrder);
+                            log.info("--------------------> 发送分账参数:  " + bean);
+                            Map<String, String> map = postForm(bean, Constant.FZ, sign, Map.class);
+                            log.info("----------------分账返回数据: " + map.toString());
+                            if (map != null) {
+                                String code = map.get("rt5_retCode");
+                                if (!"0000".equals(code)) {
+                                    String msg = map.get("rt6_retMsg");
+                                    log.info("【手动分账】>>>>>>>>>>手动分账失败>>>>>>>msg:" + msg);
+                                } else {
+                                    for (SplitAccountPo splitAccount : splitBillDetail) {
+                                        splitAccount.setMbOrderId(orderRelation.getMbOrderId());
+                                        splitAccount.setOrderRequestNo(orderRelation.getOrderRequestNo());
+                                        splitAccount.setPayStatus(1);
+                                        // 保存分账详情
+                                        newOrderDao.insertSplitAccount(splitAccount);
+                                    }
+                                    redisService.remove("XSFZMDS");
+                                    log.info("【手动分账】>>>>>>>>>>此订单分账结束");
+                                }
+                            }
+                        } catch (Exception e) {
+                            log.error("【手动分账】>>>>>>>>>>错误信息", e);
+                        }
+                    } else {
+                        // 没有佣金分账,全是成本,本笔交易已分帐
+                        newOrderDao.updateBySplitStatus(orderRelation.getMbOrderId());
+                        //没有佣金分账也解锁
+                        redisService.remove("XSFZMDS");
+                    }
                 }
+            }
+        });
+        return ResponseJson.success();
+    }
 
+    public void setSplitAccountDetail(NewShopOrder shopOrder, PayParamBo payParam, List<SplitAccountPo> list) {
+        // 待分账总金额 = 本次支付金额,单位/元
+        double splitAmount = payParam.getAllPay();
+        // 商品数据
+        List<NewOrderProduct> orderProductList = newOrderDao.getOrderProductByShopOrderId(shopOrder.getShopOrderId());
+        // 子订单付组织
+        AtomicReference<BigDecimal> totalOrganize = new AtomicReference<>();
+        // 子订单商品成本
+        AtomicReference<BigDecimal> totalCostPrice = new AtomicReference<>();
+        for (NewOrderProduct orderProduct : orderProductList) {
+            // 售价 * 数量 = 总价
+            BigDecimal total = MathUtil.mul(orderProduct.getPrice(), orderProduct.getNum());
+            // 总价 * 供应商百分比 = 成本分账金额
+            double costPrice = MathUtil.mul(total, MathUtil.div(orderProduct.getShopPercent(), 100)).doubleValue();
+            totalCostPrice.set(MathUtil.add(costPrice, totalCostPrice.get()));
+            double organize = MathUtil.mul(total, MathUtil.div(orderProduct.getOrganizePercent(), 100)).doubleValue();
+            totalOrganize.set(MathUtil.add(organize, totalOrganize.get()));
+            /**
+             * todo
+             * 出于兼容性考虑,且多次支付手续费不同,分账方式为循环每次支付记录,
+             * 当前业务满足子订单支付完成才进行分账,可以循环子订单统计支付金额,
+             * 进行一次性分账,在当前模式下如果用户分多次支付,精度损失问题较为常见。
+             */
+            // 判断是否支付过
+            Double paidAmount = newOrderDao.getOrderProductPaidAmount(orderProduct.getOrderProductId());
+            // 支付过金额大于0
+            if (null != paidAmount && MathUtil.compare(paidAmount, 0) > 0) {
+                //已付>0,成本-已付
+                costPrice = MathUtil.sub(costPrice, paidAmount).doubleValue();
             }
-            cmPayShopDao.update(payShop);
+            // 待分账金额>成本
+            if (MathUtil.compare(splitAmount, costPrice) > 0) {
+                // 待分账金额-成本
+                splitAmount = MathUtil.sub(splitAmount, costPrice).doubleValue();
+            } else {
+                costPrice = splitAmount;
+                splitAmount = 0.00;
+            }
+            if (costPrice > 0) {
+                SplitAccountPo splitAccount = new SplitAccountPo();
+                splitAccount.setShopOrderId(shopOrder.getShopOrderId());
+                splitAccount.setOrderId(shopOrder.getOrderId());
+                splitAccount.setOrderProductId(orderProduct.getOrderProductId());
+                splitAccount.setShopId(orderProduct.getShopId());
+                splitAccount.setSplitAccount(costPrice);
+                splitAccount.setProductType(1);
+                // 该商品设置了商户号
+                splitAccount.setType(4);
+                splitAccount.setSubUserNo(shopOrder.getSplitCode());
+                log.info("成本分账参数------------->" + splitAccount.toString());
+                list.add(splitAccount);
+            }
+            if (MathUtil.compare(splitAmount, 0) == 0) {
+                break;
+            }
+        }
+        /**
+         *  还有钱就付供应商运费
+         *  线上暂无供应商运费,此处逻辑空置
+         */
+
+        // 如果还有钱则为佣金,分到组织
+        if (MathUtil.compare(splitAmount, 0) > 0) {
+            // 剩余金额 - totalOrganize
+            Double amount = Math.max(totalOrganize.get().doubleValue(), 0.01);
+            splitAmount = MathUtil.sub(splitAmount, amount).doubleValue();
+            SplitAccountPo splitAccount = new SplitAccountPo();
+            splitAccount.setOrderId(shopOrder.getOrderId());
+            splitAccount.setShopOrderId(shopOrder.getShopOrderId());
+            splitAccount.setSplitAccount(amount);
+            splitAccount.setProductType(5);
+            splitAccount.setType(5);
+            /**
+             * 目前写死为联合丽格,后续有其他组织再做改动
+             */
+            splitAccount.setSubUserNo("E1807782723");
+            log.info("组织佣金分账参数------------->" + splitAccount);
+            list.add(splitAccount);
+        }
+
+        // 如果还有钱则为佣金,分到采美
+        if (MathUtil.compare(splitAmount, 0) > 0) {
+            Double amount = Math.max(splitAmount, 0.01);
+            SplitAccountPo splitAccount = new SplitAccountPo();
+            splitAccount.setOrderId(shopOrder.getOrderId());
+            splitAccount.setShopOrderId(shopOrder.getShopOrderId());
+            splitAccount.setSplitAccount(amount);
+            splitAccount.setProductType(3);
+            splitAccount.setType(5);
+            splitAccount.setSubUserNo(Constant.CUSTOMERNUM2);
+            log.info("采美佣金分账参数------------->" + splitAccount);
+            list.add(splitAccount);
+        }
+    }
+
+
+    public Map<String, String> convertBean(Object bean) {
+        Class clazz = bean.getClass();
+        Field[] fields = clazz.getDeclaredFields();
+        for (Field f : fields) {
+            f.setAccessible(true);
+        }
+        try {
+            Map<String, String> retMap = new LinkedHashMap<>();
+            for (Field f : fields) {
+                String key = f.toString().substring(f.toString().lastIndexOf(".") + 1);
+                Object value = f.get(bean);
+                if (value == null) {
+                    value = "";
+                }
+                retMap.put(key, (String) value);
+            }
+            return retMap;
+        } catch (Exception e) {
+            log.info("分账", e);
+            throw new IllegalStateException("分账异常", e);
+        }
+    }
+
+    public <T> T postForm(Map<String, String> params, String url, String sign, Class<T> clazz) {
+        FormBody.Builder builder = new FormBody.Builder();
+        for (Map.Entry<String, String> entry : params.entrySet()) {
+            builder.add(entry.getKey(), entry.getValue());
         }
+        builder.add("sign", sign);
+
+        Request request = new Request.Builder() // okHttp post
+                .url(url)
+                .post(builder.build())
+                .build();
 
+        Response response = null;
+        try {
+            response = client.newCall(request).execute();
+        } catch (IOException e) {
+            throw new IllegalStateException("请求出错", e);
+        }
+        if (!response.isSuccessful()) {
+            try {
+                log.info(response.body().string());
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            throw new RuntimeException("请求失败了: http response code: " + response.code());
+        }
 
-        return null;
+        ResponseBody body = response.body();
+        String content = null;
+        try {
+            content = body.string();
+        } catch (IOException e) {
+            throw new IllegalStateException("IO异常", e);
+        }
+        JSONObject res = JSON.parseObject(content);
+        if (!res.getBooleanValue("rt4_success")) {
+            log.error("error: " + res.getString("rt6_retMsg"));
+        }
+        /** rt4_success 为 true,需验签  **/
+        return res.toJavaObject(clazz);
     }
+
 }

+ 369 - 0
src/main/java/com/caimei/utils/ConvertUtils.java

@@ -0,0 +1,369 @@
+package com.caimei.utils;
+
+import sun.misc.BASE64Encoder;
+
+import java.io.UnsupportedEncodingException;
+import java.sql.Date;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.text.DecimalFormat;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public abstract class ConvertUtils {
+
+    private static final DecimalFormat simpleFormat = new DecimalFormat("####");
+
+    public static final boolean objectToBoolean(Object o) {
+        return o != null ? Boolean.valueOf(o.toString()).booleanValue() : false;
+    }
+
+    public static final int objectToInt(Object o) {
+        if (o instanceof Number)
+            return ((Number) o).intValue();
+        try {
+            if (o == null)
+                return -1;
+            else
+                return Integer.parseInt(o.toString());
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+    public static final short objectToShort(Object o) {
+        if (o instanceof Number)
+            return ((Number) o).shortValue();
+        try {
+            if (o == null)
+                return -1;
+            else
+                return Short.parseShort(o.toString());
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+    public static final double objectToDouble(Object o) {
+        if (o instanceof Number)
+            return ((Number) o).doubleValue();
+        try {
+            if (o == null)
+                return -1D;
+            else
+                return Double.parseDouble(o.toString());
+        } catch (NumberFormatException e) {
+            return -1D;
+        }
+    }
+
+    public static final long objectToLong(Object o) {
+        if (o instanceof Number)
+            return ((Number) o).longValue();
+        try {
+            if (o == null)
+                return -1L;
+            else
+                return Long.parseLong(o.toString());
+        } catch (NumberFormatException e) {
+            return -1L;
+        }
+    }
+
+    public static final String objectToString(Object obj, DecimalFormat fmt) {
+        fmt.setDecimalSeparatorAlwaysShown(false);
+        if (obj instanceof Double)
+            return fmt.format(((Double) obj).doubleValue());
+        if (obj instanceof Long)
+            return fmt.format(((Long) obj).longValue());
+        else
+            return obj.toString();
+    }
+
+    public static final Object getObjectValue(String value) {
+        try {
+            return Long.valueOf(value);
+        } catch (NumberFormatException e) {
+        }
+
+        try {
+            return Double.valueOf(value);
+        } catch (NumberFormatException e) {
+            return value;
+        }
+    }
+
+    public static String longToSimpleString(long value) {
+        return simpleFormat.format(value);
+    }
+
+    public static String asHex(byte hash[]) {
+        return toHex(hash);
+    }
+
+    public static String toHex(byte input[]) {
+        if (input == null)
+            return null;
+        StringBuffer output = new StringBuffer(input.length * 2);
+        for (int i = 0; i < input.length; i++) {
+            int current = input[i] & 0xff;
+            if (current < 16)
+                output.append("0");
+            output.append(Integer.toString(current, 16));
+        }
+
+        return output.toString();
+    }
+
+    public static byte[] fromHex(String input) {
+        if (input == null)
+            return null;
+        byte output[] = new byte[input.length() / 2];
+        for (int i = 0; i < output.length; i++)
+            output[i] = (byte) Integer.parseInt(input.substring(i * 2, (i + 1) * 2), 16);
+
+        return output;
+    }
+
+    public static String stringToHexString(String input, String encoding)
+            throws UnsupportedEncodingException {
+        return input != null ? toHex(input.getBytes(encoding)) : null;
+    }
+
+    public static String stringToHexString(String input) {
+        try {
+            return stringToHexString(input, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException("UTF-8 encoding is not supported by JVM");
+        }
+    }
+
+    public static String hexStringToString(String input, String encoding)
+            throws UnsupportedEncodingException {
+        return input != null ? new String(fromHex(input), encoding) : null;
+    }
+
+    public static String hexStringToString(String input) {
+        try {
+            return hexStringToString(input, "UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new IllegalStateException("UTF-8 encoding is not supported by JVM");
+        }
+    }
+
+    public static String timeZoneToCode(TimeZone tz) {
+
+        return timeZoneToString(tz);
+    }
+
+    public static TimeZone codeToTimeZone(String tzString) {
+
+        return stringToTimeZone(tzString);
+    }
+
+    public static String timeZoneToString(TimeZone tz) {
+
+        return tz != null ? tz.getID() : "";
+    }
+
+    public static TimeZone stringToTimeZone(String tzString) {
+
+        return TimeZone.getTimeZone(tzString != null ? tzString : "");
+    }
+
+    public static String localeToCode(Locale aLocale) {
+
+        return localeToString(aLocale);
+    }
+
+    public static Locale codeToLocale(String locString) {
+
+        return stringToLocale(locString);
+    }
+
+    public static String localeToString(Locale loc) {
+
+        return loc != null ? loc.toString() : "";
+    }
+
+    public static Locale stringToLocale(String locString) {
+
+        locString = locString != null ? locString.trim() : "";
+        if (locString.equals(""))
+            return new Locale("", "", "");
+        int pos = locString.indexOf(95);
+        if (pos == -1)
+            return new Locale(locString, "", "");
+        String language = locString.substring(0, pos);
+        locString = locString.substring(pos + 1);
+        pos = locString.indexOf(95);
+        if (pos == -1) {
+            return new Locale(language, locString, "");
+        } else {
+            String country = locString.substring(0, pos);
+            locString = locString.substring(pos + 1);
+            return new Locale(language, country, locString);
+        }
+    }
+
+    public static Date dateToSQLDate(java.util.Date d) {
+
+        return d != null ? new Date(d.getTime()) : null;
+    }
+
+    public static Time dateToSQLTime(java.util.Date d) {
+
+        return d != null ? new Time(d.getTime()) : null;
+    }
+
+    public static Timestamp dateToSQLTimestamp(java.util.Date d) {
+
+        return d != null ? new Timestamp(d.getTime()) : null;
+    }
+
+    public static java.util.Date sqlTimestampToDate(Timestamp t) {
+
+        return t != null ? new java.util.Date(Math.round((double) t.getTime() + (double) t.getNanos() / 1000000D)) : null;
+    }
+
+    public static Timestamp getCurrentDate() {
+
+        Calendar c = Calendar.getInstance();
+        c.set(c.get(1), c.get(2), c.get(5), 0, 0, 0);
+        Timestamp t = new Timestamp(c.getTime().getTime());
+        t.setNanos(0);
+        return t;
+    }
+
+    public static java.util.Date getDate(int y, int m, int d, boolean inclusive) {
+        java.util.Date dt = null;
+        Calendar c = Calendar.getInstance();
+        c.clear();
+        if (c.getActualMinimum(1) <= y && y <= c.getActualMaximum(1)) {
+            c.set(1, y);
+            if (c.getActualMinimum(2) <= m && m <= c.getActualMaximum(2)) {
+                c.set(2, m);
+                if (c.getActualMinimum(5) <= d && d <= c.getActualMaximum(5))
+                    c.set(5, d);
+            }
+            if (inclusive) {
+                c.add(5, 1);
+                c.add(14, -1);
+            }
+            dt = c.getTime();
+        }
+        return dt;
+    }
+
+    public static java.util.Date getDateStart(java.util.Date d) {
+
+        Calendar c = new GregorianCalendar();
+        c.clear();
+        Calendar co = new GregorianCalendar();
+        co.setTime(d);
+        c.set(Calendar.DAY_OF_MONTH, co.get(Calendar.DAY_OF_MONTH));
+        c.set(Calendar.MONTH, co.get(Calendar.MONTH));
+        c.set(Calendar.YEAR, co.get(Calendar.YEAR));
+        //c.add(Calendar.DAY_OF_MONTH,1);
+        //c.add(Calendar.MILLISECOND,-1);
+        return c.getTime();
+    }
+
+    public static java.util.Date getDateEnd(java.util.Date d) {
+        Calendar c = Calendar.getInstance();
+        c.clear();
+        Calendar co = Calendar.getInstance();
+        co.setTime(d);
+        c.set(Calendar.DAY_OF_MONTH, co.get(Calendar.DAY_OF_MONTH));
+        c.set(Calendar.MONTH, co.get(Calendar.MONTH));
+        c.set(Calendar.YEAR, co.get(Calendar.YEAR));
+        c.add(Calendar.DAY_OF_MONTH, 1);
+        c.add(Calendar.MILLISECOND, -1);
+        return c.getTime();
+    }
+
+    public static double roundNumber(double rowNumber, int roundingPoint) {
+        double base = Math.pow(10D, roundingPoint);
+        return (double) Math.round(rowNumber * base) / base;
+    }
+
+    public static Object getObject(String type, String value) throws Exception {
+
+        type = type.toLowerCase();
+        if ("boolean".equals(type))
+            return Boolean.valueOf(value);
+        if ("byte".equals(type))
+            return Byte.valueOf(value);
+        if ("short".equals(type))
+            return Short.valueOf(value);
+        if ("char".equals(type))
+            if (value.length() != 1)
+                throw new NumberFormatException("Argument is not a character!");
+            else
+                return Character.valueOf(value.toCharArray()[0]);
+        if ("int".equals(type))
+            return Integer.valueOf(value);
+        if ("long".equals(type))
+            return Long.valueOf(value);
+        if ("float".equals(type))
+            return Float.valueOf(value);
+        if ("double".equals(type))
+            return Double.valueOf(value);
+        if ("string".equals(type))
+            return value;
+        else {
+            Object objs[] = new String[]{value};
+            return Class.forName(type).getConstructor(new Class[]{
+                    String.class
+            }).newInstance(objs);
+        }
+    }
+
+    private ConvertUtils() {
+    }
+
+    /**
+     * 图片的十六进制字符串转为base64形式的字符串(去掉回车、换行字符)
+     *
+     * @param src
+     * @return
+     */
+    public static String hexStr2Base64Str(String src) {
+        byte[] bytes = hex2byte(src);
+        String strs = new BASE64Encoder().encodeBuffer(bytes);
+        StringBuilder sb = new StringBuilder(strs.length());
+        for (int i = 0; i < strs.length(); i++) {
+            if (strs.charAt(i) != '\r' && strs.charAt(i) != '\n') {
+                sb.append(strs.charAt(i));
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将十六进制字符串转为字节数组
+     *
+     * @param s
+     * @return
+     */
+    public static byte[] hex2byte(String s) {
+        byte[] src = s.toLowerCase().getBytes();
+        byte[] ret = new byte[src.length / 2];
+        for (int i = 0; i < src.length; i += 2) {
+            byte hi = src[i];
+            byte low = src[i + 1];
+            hi = (byte) ((hi >= 'a' && hi <= 'f') ? 0x0a + (hi - 'a')
+                    : hi - '0');
+            low = (byte) ((low >= 'a' && low <= 'f') ? 0x0a + (low - 'a')
+                    : low - '0');
+            ret[i / 2] = (byte) (hi << 4 | low);
+        }
+        return ret;
+    }
+//    public static void main(String[] args)
+//    {
+//    	System.out.println(getDateStart(new java.util.Date()));
+//    }
+}

+ 75 - 0
src/main/java/com/caimei/utils/Disguiser.java

@@ -0,0 +1,75 @@
+package com.caimei.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+
+/**
+ * 
+ * @ClassName: Disguiser
+ * @Description: 哈希算法的工具类,提供SHA MD5 HMAC等算法
+ *
+ */
+public class Disguiser {
+
+	public static final String ENCODE = "UTF-8";
+	private static final String KEY = "8data998mnwepxugnk03-2zirb";
+
+	public static String disguiseMD5(String message) {
+
+		if (null == message) {
+			return null;
+		}
+		return disguiseMD5(message, ENCODE);
+	}
+	
+	public static String disguise(String message){
+    	return disguise(message+KEY,ENCODE);
+    	
+    }
+	public static String disguise(String message,String encoding){
+    	message = message.trim();
+        byte value[];
+        try{
+            value = message.getBytes(encoding);
+        }
+        catch(UnsupportedEncodingException e){
+            value = message.getBytes();
+        }
+        MessageDigest md = null;
+        try{
+            md = MessageDigest.getInstance("SHA");
+        }catch(NoSuchAlgorithmException e){
+        	e.printStackTrace();
+            return null;
+        }
+        return ConvertUtils.toHex(md.digest(value));
+    }
+
+	public static String disguiseMD5(String message, String encoding) {
+
+		if (null == message || null == encoding) {
+
+			return null;
+		}
+
+		message = message.trim();
+		byte value[];
+		try {
+			value = message.getBytes(encoding);
+		} catch (UnsupportedEncodingException e) {
+			value = message.getBytes();
+		}
+		MessageDigest md = null;
+		try {
+			md = MessageDigest.getInstance("MD5");
+		} catch (NoSuchAlgorithmException e) {
+			e.printStackTrace();
+			return null;
+		}
+		return ConvertUtils.toHex(md.digest(value));
+	}
+
+
+}

+ 387 - 189
src/main/resources/mapper/NewOrderMapper.xml

@@ -4,7 +4,7 @@
         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.caimei.modules.order.dao.NewOrderDao">
     <sql id="columns">
-		a.orderId AS orderId,
+        a.orderId AS orderId,
 		a.orderNo AS orderNo,
 		a.organizeId AS organizeId,
 		a.userId AS userId,
@@ -41,175 +41,184 @@
 		a.sendOutStatus as sendOutStatus,
 		a.refundType as refundType,
 		a.postageOrderFlag AS postageOrderFlag
-	</sql>
+    </sql>
+
+    <insert id="insertSplitAccount">
+        INSERT INTO cm_split_account (orderId, productId, orderProductId, shopId, couponRecordId, vipRecordId,
+                                      authVipRecordId, type, subUserNo, splitAccount,
+                                      mbOrderId, orderRequestNo, payStatus, productType, shopOrderId, splitTime)
+        VALUES (#{orderId}, #{productId}, #{orderProductId}, #{shopId}, #{couponRecordId}, #{vipRecordId},
+                #{authVipRecordId}, #{type}, #{subUserNo}, #{splitAccount},
+                #{mbOrderId}, #{orderRequestNo}, #{payStatus}, #{productType}, #{shopOrderId}, NOW());
+    </insert>
 
     <update id="update">
-            update cm_order
-            <set>
-                <if test="orderSeen != null">
-                    orderSeen = #{orderSeen},
-                </if>
-                <if test="orderNo != null">
-                    orderNo = #{orderNo,jdbcType=VARCHAR},
-                </if>
-                <if test="userID != null">
-                    userID = #{userID,jdbcType=BIGINT},
-                </if>
-                <if test="organizeID != null">
-                    organizeID = #{organizeID,jdbcType=INTEGER},
-                </if>
-                <if test="buyUserID != null">
-                    buyUserID = #{buyUserID,jdbcType=INTEGER},
-                </if>
-                <if test="shopOrderIDs != null">
-                    shopOrderIDs = #{shopOrderIDs,jdbcType=VARCHAR},
-                </if>
-                <if test="orderSubmitType != null">
-                    orderSubmitType = #{orderSubmitType,jdbcType=CHAR},
-                </if>
-                <if test="orderType != null">
-                    orderType = #{orderType,jdbcType=CHAR},
-                </if>
-                <if test="secondHandOrderFlag != null">
-                    secondHandOrderFlag = #{secondHandOrderFlag,jdbcType=CHAR},
-                </if>
-                <if test="status != null">
-                    status = #{status,jdbcType=CHAR},
-                </if>
-                <if test="productTotalFee != null">
-                    productTotalFee = #{productTotalFee,jdbcType=DECIMAL},
-                </if>
-                <if test="orderTotalFee != null">
-                    orderTotalFee = #{orderTotalFee,jdbcType=DECIMAL},
-                </if>
-                <if test="payTotalFee != null">
-                    payTotalFee = #{payTotalFee,jdbcType=DECIMAL},
-                </if>
-                <if test="payableAmount != null">
-                    payableAmount = #{payableAmount,jdbcType=DECIMAL},
-                </if>
-                <if test="balancePayFee != null">
-                    balancePayFee = #{balancePayFee,jdbcType=DECIMAL},
-                </if>
-                <if test="discountFee != null">
-                    discountFee = #{discountFee,jdbcType=DECIMAL},
-                </if>
-                <if test="spID != null">
-                    spID = #{spID,jdbcType=BIGINT},
-                </if>
-                <if test="mainSpID != null">
-                    mainSpID = #{mainSpID,jdbcType=BIGINT},
-                </if>
-                <if test="clubID != null">
-                    clubID = #{clubID,jdbcType=BIGINT},
-                </if>
-                <if test="clubScanTime != null">
-                    clubScanTime = #{clubScanTime,jdbcType=VARCHAR},
-                </if>
-                <if test="orderSource != null">
-                    orderSource = #{orderSource,jdbcType=CHAR},
-                </if>
-                <if test="orderTime != null">
-                    orderTime = #{orderTime,jdbcType=TIMESTAMP},
-                </if>
-                <if test="productCount != null">
-                    productCount = #{productCount,jdbcType=INTEGER},
-                </if>
-                <if test="presentCount != null">
-                    presentCount = #{presentCount,jdbcType=INTEGER},
-                </if>
-                <if test="confirmFlag != null">
-                    confirmFlag = #{confirmFlag,jdbcType=CHAR},
-                </if>
-                <if test="clauseID != null">
-                    clauseID = #{clauseID,jdbcType=BIGINT},
-                </if>
-                <if test="clauseName != null">
-                    clauseName = #{clauseName,jdbcType=VARCHAR},
-                </if>
-                <if test="freePostFlag != null">
-                    freePostFlag = #{freePostFlag,jdbcType=CHAR},
-                </if>
-                <if test="freight != null">
-                    freight = #{freight,jdbcType=DECIMAL},
-                </if>
-                <if test="delFlag != null">
-                    delFlag = #{delFlag,jdbcType=CHAR},
-                </if>
-                <if test="note != null">
-                    note = #{note,jdbcType=LONGVARCHAR},
-                </if>
-                <if test="clauseContent != null">
-                    clauseContent = #{clauseContent,jdbcType=LONGVARCHAR},
-                </if>
-                <if test="payTime != null">
-                    payTime = #{payTime,jdbcType=LONGVARCHAR},
-                </if>
-                <if test="preferential != null">
-                    preferential = #{preferential ,jdbcType=DECIMAL},
-                </if>
-                <if test="discountFee != null">
-                    discountFee = #{discountFee},
-                </if>
-                <if test="payFlag != null">
-                    payFlag = #{payFlag},
-                </if>
-                <if test="onlinePayFlag != null">
-                    onlinePayFlag = #{onlinePayFlag},
-                </if>
-                <if test="splitFlag != null">
-                    splitFlag = #{splitFlag},
-                </if>
-                <if test="closeReason != null">
-                    closeReason = #{closeReason},
-                </if>
-                <if test="confirmTime != null">
-                    confirmTime = #{confirmTime},
-                </if>
-                <if test="invoiceFlag != null">
-                    invoiceFlag = #{invoiceFlag},
-                </if>
-                <if test="postageOrderFlag != null">
-                    postageOrderFlag = #{postageOrderFlag},
-                </if>
-                <if test="sendOutStatus != null">
-                    sendOutStatus = #{sendOutStatus},
-                </if>
-                <if test="receiptStatus != null">
-                    receiptStatus = #{receiptStatus},
-                </if>
-                <if test="payStatus != null">
-                    payStatus = #{payStatus},
-                </if>
-                <if test="refundType != null">
-                    refundType = #{refundType},
-                </if>
-                <if test="promotionFullReduction != null">
-                    promotionFullReduction = #{promotionFullReduction},
-                </if>
-                <if test="promotionalGiftsCount != null">
-                    promotionalGiftsCount = #{promotionalGiftsCount},
-                </if>
-                <if test="affirmPaymentFlag != null">
-                    affirmPaymentFlag = #{affirmPaymentFlag},
-                </if>
-                <if test="rebateFlag != null">
-                    rebateFlag = #{rebateFlag},
-                </if>
-                <if test="rebateFee != null">
-                    rebateFee = #{rebateFee},
-                </if>
-                <if test="zeroCostFlag != null">
-                    zeroCostFlag = #{zeroCostFlag},
-                </if>
-                <if test="couponAmount != null">
-                    couponAmount = #{couponAmount},
-                </if>
-                <if test="svipFullReduction != null">
-                    svipFullReduction = #{svipFullReduction}
-                </if>
-            </set>
-            where orderID = #{orderId}
+        update cm_order
+        <set>
+            <if test="orderSeen != null">
+                orderSeen = #{orderSeen},
+            </if>
+            <if test="orderNo != null">
+                orderNo = #{orderNo,jdbcType=VARCHAR},
+            </if>
+            <if test="userID != null">
+                userID = #{userID,jdbcType=BIGINT},
+            </if>
+            <if test="organizeID != null">
+                organizeID = #{organizeID,jdbcType=INTEGER},
+            </if>
+            <if test="buyUserID != null">
+                buyUserID = #{buyUserID,jdbcType=INTEGER},
+            </if>
+            <if test="shopOrderIDs != null">
+                shopOrderIDs = #{shopOrderIDs,jdbcType=VARCHAR},
+            </if>
+            <if test="orderSubmitType != null">
+                orderSubmitType = #{orderSubmitType,jdbcType=CHAR},
+            </if>
+            <if test="orderType != null">
+                orderType = #{orderType,jdbcType=CHAR},
+            </if>
+            <if test="secondHandOrderFlag != null">
+                secondHandOrderFlag = #{secondHandOrderFlag,jdbcType=CHAR},
+            </if>
+            <if test="status != null">
+                status = #{status,jdbcType=CHAR},
+            </if>
+            <if test="productTotalFee != null">
+                productTotalFee = #{productTotalFee,jdbcType=DECIMAL},
+            </if>
+            <if test="orderTotalFee != null">
+                orderTotalFee = #{orderTotalFee,jdbcType=DECIMAL},
+            </if>
+            <if test="payTotalFee != null">
+                payTotalFee = #{payTotalFee,jdbcType=DECIMAL},
+            </if>
+            <if test="payableAmount != null">
+                payableAmount = #{payableAmount,jdbcType=DECIMAL},
+            </if>
+            <if test="balancePayFee != null">
+                balancePayFee = #{balancePayFee,jdbcType=DECIMAL},
+            </if>
+            <if test="discountFee != null">
+                discountFee = #{discountFee,jdbcType=DECIMAL},
+            </if>
+            <if test="spID != null">
+                spID = #{spID,jdbcType=BIGINT},
+            </if>
+            <if test="mainSpID != null">
+                mainSpID = #{mainSpID,jdbcType=BIGINT},
+            </if>
+            <if test="clubID != null">
+                clubID = #{clubID,jdbcType=BIGINT},
+            </if>
+            <if test="clubScanTime != null">
+                clubScanTime = #{clubScanTime,jdbcType=VARCHAR},
+            </if>
+            <if test="orderSource != null">
+                orderSource = #{orderSource,jdbcType=CHAR},
+            </if>
+            <if test="orderTime != null">
+                orderTime = #{orderTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="productCount != null">
+                productCount = #{productCount,jdbcType=INTEGER},
+            </if>
+            <if test="presentCount != null">
+                presentCount = #{presentCount,jdbcType=INTEGER},
+            </if>
+            <if test="confirmFlag != null">
+                confirmFlag = #{confirmFlag,jdbcType=CHAR},
+            </if>
+            <if test="clauseID != null">
+                clauseID = #{clauseID,jdbcType=BIGINT},
+            </if>
+            <if test="clauseName != null">
+                clauseName = #{clauseName,jdbcType=VARCHAR},
+            </if>
+            <if test="freePostFlag != null">
+                freePostFlag = #{freePostFlag,jdbcType=CHAR},
+            </if>
+            <if test="freight != null">
+                freight = #{freight,jdbcType=DECIMAL},
+            </if>
+            <if test="delFlag != null">
+                delFlag = #{delFlag,jdbcType=CHAR},
+            </if>
+            <if test="note != null">
+                note = #{note,jdbcType=LONGVARCHAR},
+            </if>
+            <if test="clauseContent != null">
+                clauseContent = #{clauseContent,jdbcType=LONGVARCHAR},
+            </if>
+            <if test="payTime != null">
+                payTime = #{payTime,jdbcType=LONGVARCHAR},
+            </if>
+            <if test="preferential != null">
+                preferential = #{preferential ,jdbcType=DECIMAL},
+            </if>
+            <if test="discountFee != null">
+                discountFee = #{discountFee},
+            </if>
+            <if test="payFlag != null">
+                payFlag = #{payFlag},
+            </if>
+            <if test="onlinePayFlag != null">
+                onlinePayFlag = #{onlinePayFlag},
+            </if>
+            <if test="splitFlag != null">
+                splitFlag = #{splitFlag},
+            </if>
+            <if test="closeReason != null">
+                closeReason = #{closeReason},
+            </if>
+            <if test="confirmTime != null">
+                confirmTime = #{confirmTime},
+            </if>
+            <if test="invoiceFlag != null">
+                invoiceFlag = #{invoiceFlag},
+            </if>
+            <if test="postageOrderFlag != null">
+                postageOrderFlag = #{postageOrderFlag},
+            </if>
+            <if test="sendOutStatus != null">
+                sendOutStatus = #{sendOutStatus},
+            </if>
+            <if test="receiptStatus != null">
+                receiptStatus = #{receiptStatus},
+            </if>
+            <if test="payStatus != null">
+                payStatus = #{payStatus},
+            </if>
+            <if test="refundType != null">
+                refundType = #{refundType},
+            </if>
+            <if test="promotionFullReduction != null">
+                promotionFullReduction = #{promotionFullReduction},
+            </if>
+            <if test="promotionalGiftsCount != null">
+                promotionalGiftsCount = #{promotionalGiftsCount},
+            </if>
+            <if test="affirmPaymentFlag != null">
+                affirmPaymentFlag = #{affirmPaymentFlag},
+            </if>
+            <if test="rebateFlag != null">
+                rebateFlag = #{rebateFlag},
+            </if>
+            <if test="rebateFee != null">
+                rebateFee = #{rebateFee},
+            </if>
+            <if test="zeroCostFlag != null">
+                zeroCostFlag = #{zeroCostFlag},
+            </if>
+            <if test="couponAmount != null">
+                couponAmount = #{couponAmount},
+            </if>
+            <if test="svipFullReduction != null">
+                svipFullReduction = #{svipFullReduction}
+            </if>
+        </set>
+        where orderID = #{orderId}
     </update>
 
     <update id="updatePayStatus">
@@ -218,6 +227,19 @@
         where orderID = #{orderId}
     </update>
 
+    <update id="updateShopOrderByPayStatus">
+        UPDATE cm_shop_order
+        SET payStatus       = #{payStatus},
+            payedShopAmount = #{paidShop}
+        WHERE shopOrderID = #{shopOrderId}
+    </update>
+
+    <update id="updateBySplitStatus">
+        UPDATE cm_receipt_order_relation
+        SET splitStatus = 1
+        WHERE mbOrderId = #{mbOrderId}
+    </update>
+
     <resultMap id="orderDisplayList" type="com.caimei.modules.order.entity.NewOrder">
         <id column="orderId" property="orderId"/>
         <result column="orderNo" property="orderNo"/>
@@ -251,7 +273,8 @@
         co.sendOutStatus AS sendOutStatus,
         co.receiptStatus AS receiptStatus,
         co.productCount AS productCount,
-        (SELECT IFNULL(sum(cop.shouldPayFee),0) FROM cm_order_product cop WHERE cop.orderId=co.orderId) AS "shouldPayProduct",
+        (SELECT IFNULL(sum(cop.shouldPayFee),0) FROM cm_order_product cop WHERE cop.orderId=co.orderId) AS
+        "shouldPayProduct",
         co.status AS status,
         co.postageOrderFlag AS postageOrderFlag
         FROM cm_order co
@@ -315,7 +338,8 @@
                 <if test="returnedPurchaseStatus == 0">
                     not exists
                 </if>
-                (select 1 from cm_returned_purchase c3 where c3.status = '1' and c3.orderId = co.orderId and c3.delFlag = 0)
+                (select 1 from cm_returned_purchase c3 where c3.status = '1' and c3.orderId = co.orderId and c3.delFlag
+                = 0)
             </if>
             <if test="refundType != null and refundType != ''">
                 AND
@@ -331,16 +355,20 @@
             </if>
             <if test="orderRefundType != null and orderRefundType != ''">
                 <if test="orderRefundType == 0">
-                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId  and crp.delFlag = 0) = 0
+                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.delFlag =
+                    0) = 0
                 </if>
                 <if test="orderRefundType == 1">
-                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId  and crp.delFlag = 0) > 0
+                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.delFlag =
+                    0) > 0
                 </if>
                 <if test="orderRefundType == 11">
-                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 1  and crp.delFlag = 0) > 0
+                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 1
+                    and crp.delFlag = 0) > 0
                 </if>
                 <if test="orderRefundType == 12">
-                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 2 and crp.delFlag = 0
+                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 2
+                    and crp.delFlag = 0
                     <if test="startRefundTime != null and startRefundTime != ''">
                         AND crp.confirmReturnTime <![CDATA[  >=  ]]> #{startRefundTime}
                     </if>
@@ -350,31 +378,201 @@
                     ) > 0
                 </if>
                 <if test="orderRefundType == 13">
-                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 3 and crp.delFlag = 0) > 0
+                    AND (select count(1) from cm_returned_purchase crp where co.orderId = crp.orderId and crp.status = 3
+                    and crp.delFlag = 0) > 0
                 </if>
             </if>
             AND co.delFlag = 0
         </where>
-            ORDER BY co.orderId DESC, co.orderTime DESC
+        ORDER BY co.orderId DESC, co.orderTime DESC
     </select>
 
     <select id="loadShopOrders" parameterType="string" resultType="com.caimei.modules.order.entity.NewShopOrder">
-		SELECT
-		cs.shopOrderId AS shopOrderId,
-		cs.shopOrderNo AS shopOrderNo,
-		cs.shopOrderNo AS shopOrderNo,
-		cs.itemCount AS itemCount,
-		cs.needPayAmount AS needPayAmount,
-		s.name AS shopName,
-		cs.shopId AS shopId
-		FROM cm_shop_order cs
-		LEFT JOIN shop s ON cs.shopId = s.shopId
-		WHERE cs.orderNo = #{orderNo} AND cs.delFlag = 0
-	</select>
+        SELECT cs.shopOrderId   AS shopOrderId,
+               cs.shopOrderNo   AS shopOrderNo,
+               cs.shopOrderNo   AS shopOrderNo,
+               cs.itemCount     AS itemCount,
+               cs.needPayAmount AS needPayAmount,
+               s.name           AS shopName,
+               cs.shopId        AS shopId
+        FROM cm_shop_order cs
+                 LEFT JOIN shop s ON cs.shopId = s.shopId
+        WHERE cs.orderNo = #{orderNo}
+          AND cs.delFlag = 0
+    </select>
 
     <select id="get" resultType="com.caimei.modules.order.entity.NewOrder">
-        SELECT <include refid="columns"/>
+        SELECT
+        <include refid="columns"/>
         FROM cm_order a
         WHERE a.orderId = #{id}
     </select>
+
+    <select id="getUndividedPaidReceipt" resultType="com.caimei.modules.order.entity.CmReceiptOrderRelation">
+        SELECT cror.id,
+               cror.relationType,
+               cror.receiptId,
+               cror.associateAmount,
+               cror.orderId,
+               cror.delFlag,
+               cror.mbOrderId,
+               cror.orderRequestNo,
+               cror.splitStatus,
+               cror.shopOrderId,
+               cdr.payType
+        FROM cm_receipt_order_relation cror
+                 LEFT JOIN cm_discern_receipt cdr ON cror.receiptID = cdr.id
+                 LEFT JOIN cm_order co ON cror.orderID = co.orderID
+                 left join cm_shop_order cso on cso.orderId = cror.orderID
+                 LEFT JOIN cm_order_product cop ON co.shopOrderIDs = cop.shopOrderID
+                 LEFT JOIN product p ON cop.productID = p.productID
+        WHERE cror.relationType = 2
+          and cror.shopOrderId = #{shopOrderId}
+          AND cso.receiptStatus = 3
+          AND cror.delFlag = 0
+          AND cror.mbOrderId IS NOT NULL
+          AND cror.splitStatus = 0
+          AND cdr.payWay = 1
+          AND cdr.receiptDate <![CDATA[  <=  ]]> #{currentTime}
+          AND co.organizeID = 0
+          AND co.orderType != 2
+          AND co.refundType != 2
+          AND p.splitCode != 'E1807059160'
+    </select>
+
+    <select id="getShopOrderListByOrderId" resultType="com.caimei.modules.order.entity.NewShopOrder">
+        SELECT shopOrderID AS shopOrderId,
+               shopOrderNo,
+               orderID     AS orderId,
+               orderNo,
+               shopID      AS shopId,
+               note,
+               userID      AS userId,
+               clubID      AS clubId,
+               spID        AS spId,
+               brokerage,
+               itemCount,
+               totalAmount,
+               productAmount,
+               needPayAmount,
+               shopProductAmount,
+               shopPostFee,
+               shouldPayShopAmount,
+               orderTime,
+               payStatus,
+               splitCode
+        FROM cm_shop_order
+        WHERE delFlag = 0
+          AND shopOrderID = #{shopOrderId}
+    </select>
+
+    <select id="getSplitAccountList" resultType="com.caimei.modules.order.entity.SplitAccountPo">
+        SELECT id,
+               orderId,
+               productId,
+               orderProductId,
+               shopId,
+               type,
+               subUserNo,
+               SUM(splitAccount) AS splitAccount,
+               mbOrderId,
+               orderRequestNo,
+               payStatus,
+               productType
+        FROM cm_split_account
+        WHERE type = 4
+          AND payStatus = 1
+          AND splitAccount > 0
+          AND mbOrderId = #{mbOrderId}
+        GROUP BY shopId
+    </select>
+
+    <select id="getShopOrderByOrderId" resultType="com.caimei.modules.order.entity.NewShopOrder">
+        SELECT shopOrderID AS shopOrderId,
+               shopOrderNo,
+               orderID     AS orderId,
+               orderNo,
+               shopID      AS shopId,
+               note,
+               userID      AS userId,
+               clubID      AS clubId,
+               spID        AS spId,
+               orderPromotionsId,
+               promotionFullReduction,
+               brokerage,
+               canRefundAmount,
+               itemCount,
+               totalAmount,
+               productAmount,
+               needPayAmount,
+               shopProductAmount,
+               shopPostFee,
+               shopTaxFee,
+               shouldPayShopAmount,
+               orderTime,
+               orderSubmitType,
+               payStatus,
+               sendOutStatus,
+               splitFlag,
+               splitCode
+        FROM cm_shop_order
+        WHERE delFlag = 0
+          AND orderID = #{orderId}
+    </select>
+
+    <select id="getPaidShopAmount" resultType="java.lang.Double">
+        SELECT SUM(payAmount)
+        FROM cm_pay_shop_record
+        WHERE STATUS = 1
+          AND delFlag = 0
+          AND shopOrderID = #{shopOrderId}
+    </select>
+
+    <select id="getOrderProductByShopOrderId" resultType="com.caimei.modules.order.entity.NewOrderProduct">
+        SELECT cop.orderProductID                                                 AS orderProductId,
+               cop.orderID                                                        AS orderId,
+               cop.orderNo,
+               cop.shopOrderID                                                    AS shopOrderId,
+               cop.shopOrderNo,
+               cop.productId,
+               cop.shopId,
+               cop.name,
+               cop.productImage                                                   AS image,
+               cop.price,
+               cop.shopName,
+               IF(cop.shopid = 998 AND co.freight > 0, co.freight, cop.costPrice) AS costPrice,
+               cop.normalPrice,
+               cop.totalAmount,
+               cop.totalFee,
+               cop.shouldPayFee,
+               cop.productUnit,
+               cop.num,
+               cop.presentNum,
+               cop.discountFee,
+               cop.shopProductAmount,
+               cop.singleShopFee,
+               cop.shopFee,
+               cop.singleCmFee,
+               cop.cmFee,
+               p.productCategory                                                  as productCategory,
+               p.splitCode,
+               cmp.cmPercent,
+               cmp.organizePercent,
+               cmp.shopPercent
+        FROM cm_order_product cop
+        LEFT JOIN product p ON cop.productID = p.productID
+        left join cm_order co on co.orderID = cop.orderID
+        left join cm_mall_product_sku cmp on cop.organizeSkuId = cmp.id
+        WHERE cop.shopOrderID = #{shopOrderId}
+          AND IF(co.userBeans = 0, 1 = 1, cop.shopid != 998)
+        ORDER BY cop.discountPrice DESC
+    </select>
+
+    <select id="getOrderProductPaidAmount" resultType="java.lang.Double">
+        SELECT SUM(splitAccount)
+        FROM cm_split_account
+        WHERE orderProductId = #{orderProductId}
+          AND payStatus = 1
+          AND productType = 1
+    </select>
 </mapper>

+ 1 - 1
src/main/resources/mapper/NewShopOrderMapper.xml

@@ -192,7 +192,7 @@
 
     <update id="outPaying">
         update cm_shop_order
-        set paying = '0'
+        set paying = 0
         where shopOrderID in
               (select cpsr.shopOrderID
                from cm_pay_shop_record cpsr

+ 39 - 2
src/main/resources/mapper/PayShopDao.xml

@@ -44,9 +44,9 @@
 
     <insert id="insertPayRecord">
         insert into cm_pay_shop_record(shopID, shopOrderID, shopOrderNo, payAmount, payCmAmount,
-                                       paymentType, payType, payShopID, status)
+                                       paymentType, payType, payShopID, status, payTime)
         values (#{shopId}, #{shopOrderId}, #{shopOrderNo}, #{payAmount}, #{payCmAmount}, 1, #{payType},
-                #{payShopId}, #{status})
+                #{payShopId}, #{status}, #{payTime})
     </insert>
 
     <update id="updatePayRecord">
@@ -87,6 +87,43 @@
         where shopOrderID = #{shopOrderId}
     </update>
 
+    <update id="updatePayShopDetail">
+        UPDATE cm_pay_shop
+        SET name        = #{name},
+            totalAmount = #{totalAmount},
+            payType     = #{payType},
+            applicant   = #{applicant},
+            applyTime   = #{applyTime},
+            reviewer    = #{reviewer},
+            reviewTime  = #{reviewTime},
+            status      = #{status},
+            reason      = #{reason},
+            delFlag     = #{delFlag}
+        WHERE id = #{payShopId}
+    </update>
+
+    <update id="updateRecordById">
+        update cm_pay_shop_record
+        set payAmount   = #{waitPayShop},
+            payCmAmount = #{waitPayCmAmount}
+        where payShopID = #{payShopId}
+          and shopOrderID = #{shopOrderId}
+    </update>
+
+    <update id="updateShopAccount">
+        update shop
+        set bankAccountName = #{bankAccountName},
+            bankName        = #{bankName},
+            bankAccount     = #{bankAccount}
+        where shopId = #{shopId}
+    </update>
+
+    <update id="deleteRecords">
+        update cm_pay_shop_record
+        set delFlag = 1
+        where payShopID = #{id}
+    </update>
+
     <select id="findPayShops" resultType="com.caimei.modules.order.entity.OrderPayShop">
         SELECT
         a.id AS "payShopId",

+ 0 - 36
src/test/java/com/caimei/TestDao.java

@@ -1,36 +0,0 @@
-package com.caimei;
-
-import com.caimei.modules.shiro.dao.UserDao;
-import com.caimei.modules.shiro.entity.CmMallAdminUser;
-import com.caimei.utils.MD5Util;
-import junit.framework.TestCase;
-import org.junit.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.context.annotation.ComponentScan;
-
-import javax.annotation.Resource;
-import java.util.Date;
-
-/**
- * Description
- *
- * @author : Charles
- * @date : 2020/2/25
- */
-@SpringBootTest
-public class TestDao {
-
-    @Test
-    public void testSign() {
-        CmMallAdminUser user = new CmMallAdminUser();
-        user.setAccount("chaooo");
-        user.setPassword("123456");
-        user.setSalt("55120f70");
-        user.setAccountName("超超");
-        user.setOrganizeId(1);
-        String md5Pass = MD5Util.md5(user.getPassword() + user.getSalt());
-        user.setPassword(md5Pass);
-        System.out.println(md5Pass);
-        TestCase.assertNotNull(user);
-    }
-}

+ 0 - 113
src/test/java/com/caimei/TokenUtils.java

@@ -1,113 +0,0 @@
-package com.caimei;
-
-import com.caimei.utils.TokenEncryptUtils;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-/**
- * token生成和校验
- *
- * @author plf
- */
-public class TokenUtils {
-
-    private static Map<String, String> MAP_TOKENS = new HashMap<String, String>();
-    private static final int VALID_TIME = 60 * 60 * 2; // token有效期(秒)
-    public static final String TOKEN_ERROR = "F"; // 非法
-    public static final String TOKEN_OVERDUE = "G"; // 过期
-    public static final String TOKEN_FAILURE = "S"; // 失效
-
-    /**
-     * 生成token,该token长度不一致,如需一致,可自行MD5或者其它方式加密一下
-     * 该方式的token只存在磁盘上,如果项目是分布式,最好用redis存储
-     *
-     * @param str: 该字符串可自定义,在校验token时要保持一致
-     * @return
-     */
-    public static String getToken(String str) {
-        String token = TokenEncryptUtils.encoded(getCurrentTime() + "," + str);
-        MAP_TOKENS.put(str, token);
-        return token;
-    }
-
-    /**
-     * 校验token的有效性
-     *
-     * @param token
-     * @return
-     */
-    public static String checkToken(String token) {
-        if (token == null) {
-            return TOKEN_ERROR;
-        }
-        try {
-            String[] tArr = TokenEncryptUtils.decoded(token).split(",");
-            if (tArr.length != 2) {
-                return TOKEN_ERROR;
-            }
-            // token生成时间戳
-            int tokenTime = Integer.parseInt(tArr[0]);
-            // 当前时间戳
-            int currentTime = getCurrentTime();
-            if (currentTime - tokenTime < VALID_TIME) {
-                String tokenStr = tArr[1];
-                String mToken = MAP_TOKENS.get(tokenStr);
-                if (mToken == null) {
-                    return TOKEN_OVERDUE;
-                } else if (!mToken.equals(token)) {
-                    return TOKEN_FAILURE;
-                }
-                return tokenStr;
-            } else {
-                return TOKEN_OVERDUE;
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        return TOKEN_ERROR;
-    }
-
-    /**
-     * 获取当前时间戳(10位整数)
-     */
-    public static int getCurrentTime() {
-        return (int) (System.currentTimeMillis() / 1000);
-    }
-
-    /**
-     * 移除过期的token
-     */
-    public static void removeInvalidToken() {
-        int currentTime = getCurrentTime();
-        for (Entry<String, String> entry : MAP_TOKENS.entrySet()) {
-            String[] tArr = TokenEncryptUtils.decoded(entry.getValue()).split(",");
-            int tokenTime = Integer.parseInt(tArr[0]);
-            if (currentTime - tokenTime > VALID_TIME) {
-                MAP_TOKENS.remove(entry.getKey());
-            }
-        }
-    }
-
-    /**
-     * 测试
-     *
-     * @param args
-     */
-    public static void main(String[] args) {
-        String str = "username_and_password";
-
-        // 获取token
-        String token = TokenUtils.getToken(str);
-        System.out.println("token Result: " + token);
-
-        // 校验token
-        String checkToken = TokenUtils.checkToken(token);
-        System.out.println("checkToken Result: " + checkToken);
-        if (str.equals(checkToken)) {
-            System.out.println("==>token verification succeeded!");
-        }
-
-    }
-}