From d4f159d60acf6f263bfa4508a113c0feacd2f5b9 Mon Sep 17 00:00:00 2001
From: mitao <2763622819@qq.com>
Date: 星期三, 19 六月 2024 18:30:02 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ToolUtil.java                                   |  718 +++++++
 ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml                                    |   17 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java                  |  126 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/JwtProperties.java                   |   71 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/PageKit.java                            |   52 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HexKit.java                             |  259 ++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafKit.java                             |  114 +
 ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/IMemberService.java                        |    2 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/StrKit.java                             | 1374 ++++++++++++++
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java      |   21 
 ruoyi-modules/ruoyi-order/pom.xml                                                                            |   18 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTimeKit.java                        |  709 +++++++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/restTemplate/RestTemplateConfig.java                 |   15 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTime.java                           |   70 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/MD5AndKL.java                                   |  116 +
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/ObjectKit.java                          |   21 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HttpKit.java                            |  196 ++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/LogisticsServiceImpl.java               |   55 
 ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/controller/forepart/ForepartMemberController.java  |    6 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/RestProperties.java                  |   57 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartOrderController.java     |    7 
 ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/GoodsGroupPurchaseInfoVO.java        |    4 
 ruoyi-modules/ruoyi-order/src/main/resources/conf/param.properties                                           |    8 
 ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java                |    5 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/BasicType.java                          |   38 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java                   |  125 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/PayProperties.java                   |   74 
 /dev/null                                                                                                    |  287 ---
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/CollectionKit.java                      |  833 ++++++++
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartLogisticsController.java |    7 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/ILogisticsService.java                       |    2 
 ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/MemberServiceImpl.java                |   14 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafRequestWrapper.java                  |  149 +
 ruoyi-api/ruoyi-api-system/pom.xml                                                                           |    2 
 ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/vo/KuaiDiCode.java                                   |   14 
 35 files changed, 5,190 insertions(+), 396 deletions(-)

diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml
index dba587c..0f6f7ba 100644
--- a/ruoyi-api/ruoyi-api-system/pom.xml
+++ b/ruoyi-api/ruoyi-api-system/pom.xml
@@ -39,6 +39,8 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-websocket</artifactId>
         </dependency>
+
+
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/GoodsGroupPurchaseInfoVO.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/GoodsGroupPurchaseInfoVO.java
index b559987..e0ba88d 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/GoodsGroupPurchaseInfoVO.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/vo/GoodsGroupPurchaseInfoVO.java
@@ -91,4 +91,8 @@
     @ApiModelProperty(value = "團購商品訂單")
     @JsonInclude(JsonInclude.Include.ALWAYS)
     private Order order;
+
+    @ApiModelProperty(value = "是收藏 1未收藏,2收藏")
+    @JsonInclude(JsonInclude.Include.ALWAYS)
+    private Integer isCollection;
 }
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
index 38dc737..4f10ab6 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsGroupPurchaseServiceImpl.java
@@ -21,9 +21,11 @@
 import com.ruoyi.goods.controller.management.dto.GoodsGroupPurchaseDTO;
 import com.ruoyi.goods.controller.management.dto.GoodsGroupPurchaseQuery;
 import com.ruoyi.goods.controller.management.vo.GoodsGroupPurchaseVO;
+import com.ruoyi.goods.domain.MemberGoodsCollection;
 import com.ruoyi.goods.mapper.GoodsGroupPurchaseMapper;
 import com.ruoyi.goods.service.IGoodsGroupPurchaseService;
 import com.ruoyi.goods.service.IGoodsSkuService;
+import com.ruoyi.goods.service.IMemberGoodsCollectionService;
 import com.ruoyi.goods.service.async.AsyncMethodService;
 import com.ruoyi.system.api.constants.DelayTaskEnum;
 import com.ruoyi.system.api.constants.NotificationTypeConstant;
@@ -68,6 +70,9 @@
     private final IGoodsSkuService goodsSkuService;
     private final AsyncMethodService asyncMethodService;
     private final RedisService redisService;
+
+    @Resource
+    private IMemberGoodsCollectionService iMemberGoodsCollectionService;
     // 创建一个静态共享的ObjectMapper实例以重用
     private static final ObjectMapper objectMapper = new ObjectMapper();
     /**
@@ -319,7 +324,21 @@
         goodsGroupPurchaseInfoVO.setListingStatus(one.getListingStatus());
         goodsGroupPurchaseInfoVO.setGroupStatus(one.getGroupStatus());
 
-        Order data = orderClient.getOrderByGroupPurchaseMemberId(homeGoodsSkuDTO, SecurityConstants.INNER).getData();
+        LambdaQueryWrapper<MemberGoodsCollection> wrapper4= Wrappers.lambdaQuery();
+        wrapper4.eq(MemberGoodsCollection::getDelFlag,0);
+        wrapper4.eq(MemberGoodsCollection::getMemberId,homeGoodsSkuDTO.getMemberId());
+        wrapper4.eq(MemberGoodsCollection::getTargetId,one.getId());
+        wrapper4.eq(MemberGoodsCollection::getType,1);
+        List<MemberGoodsCollection> list = iMemberGoodsCollectionService.list(wrapper4);
+        if (list.size()>0){
+            goodsGroupPurchaseInfoVO.setIsCollection(2);
+        }else{
+            goodsGroupPurchaseInfoVO.setIsCollection(1);
+        }
+        HomeGoodsSkuDTO homeGoodsSkuDTO1=new HomeGoodsSkuDTO();
+        homeGoodsSkuDTO1.setGoodsSkuId(one.getId());
+        homeGoodsSkuDTO1.setMemberId(homeGoodsSkuDTO.getMemberId());
+        Order data = orderClient.getOrderByGroupPurchaseMemberId(homeGoodsSkuDTO1, SecurityConstants.INNER).getData();
         if (data!=null){
             goodsGroupPurchaseInfoVO.setIsGoodsGroupPurchase(2);
             goodsGroupPurchaseInfoVO.setOrder(data);
diff --git a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java
index 6f15c87..938eca7 100644
--- a/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java
+++ b/ruoyi-modules/ruoyi-goods/src/main/java/com/ruoyi/goods/service/impl/GoodsSkuServiceImpl.java
@@ -33,6 +33,7 @@
 import com.ruoyi.system.api.domain.dto.ListStatusDTO;
 import com.ruoyi.system.api.domain.vo.HomeGoodsSkuInfoVO;
 import com.ruoyi.system.api.domain.vo.HomeGoodsSkuListVO;
+import com.ruoyi.system.api.domain.vo.OrderVO;
 import com.ruoyi.system.api.domain.vo.getHomeGoodsSkuXxiVO;
 import com.ruoyi.system.api.feignClient.GoodsSkuClient;
 
@@ -426,8 +427,8 @@
             HomeGoodsSkuDTO homeGoodsSkuDTO1 =new HomeGoodsSkuDTO();
             homeGoodsSkuDTO1.setGoodsSkuId(goodsGroupPurchase.getId());
             homeGoodsSkuDTO1.setMemberId(homeGoodsSkuDTO.getMemberId());
-            Order data5 = orderClient.getOrderByGroupPurchaseMemberId(homeGoodsSkuDTO1, SecurityConstants.INNER).getData();
-            if (data5!=null){
+            List<OrderVO> data4 = orderClient.getOrderByGroupPurchaseMemberList(homeGoodsSkuDTO1, SecurityConstants.INNER).getData();
+            if (data4!=null){
                 homeGoodsSkuInfoVO.setIsGoodsGroupPurchase(2);
             }else{
                 homeGoodsSkuInfoVO.setIsGoodsGroupPurchase(1);
diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/controller/forepart/ForepartMemberController.java b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/controller/forepart/ForepartMemberController.java
index 820a605..8801954 100644
--- a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/controller/forepart/ForepartMemberController.java
+++ b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/controller/forepart/ForepartMemberController.java
@@ -54,9 +54,9 @@
 
     @PostMapping(value = "/mobile")
     @ApiOperation(value = "用户端-小程序获取电话号码")
-    public R mobile(@RequestBody MobileDTO mobileDTO) {
-         iMemberService.mobile(mobileDTO);
-        return R.ok();
+    public R<String> mobile(@RequestBody MobileDTO mobileDTO) {
+
+        return R.ok(iMemberService.mobile(mobileDTO));
     }
 
     @PostMapping("/getMembeid")
diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/IMemberService.java b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/IMemberService.java
index 3536ffc..8b074fb 100644
--- a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/IMemberService.java
+++ b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/IMemberService.java
@@ -37,7 +37,7 @@
     List<Member> getMemberListByIds(Collection<Long> memberIdList);
 
 
-    void mobile(@RequestBody MobileDTO mobileDTO);
+    String mobile(@RequestBody MobileDTO mobileDTO);
 
     /**
      * 获取会员管理分页列表
diff --git a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/MemberServiceImpl.java b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/MemberServiceImpl.java
index 69e1e96..55a5eb0 100644
--- a/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/MemberServiceImpl.java
+++ b/ruoyi-modules/ruoyi-member/src/main/java/com/ruoyi/member/service/impl/MemberServiceImpl.java
@@ -186,6 +186,7 @@
                         sysUser = new SysUser();
                         sysUser.setUserName(memberId);
                         sysUser.setNickName("白金用户");
+                        sysUser.setUserType("03");
                         sysUser.setPhonenumber(response.getOpenId());
                         sysUser.setAvatar("https://hongruitang.oss-cn-beijing.aliyuncs.com/default.png");
                         String password = "123456";
@@ -243,6 +244,7 @@
                         sysUser = new SysUser();
                         sysUser.setUserName(memberId);
                         sysUser.setNickName("白金用户");
+                        sysUser.setUserType("03");
                         sysUser.setAvatar("https://hongruitang.oss-cn-beijing.aliyuncs.com/default.png");
                         String password = "123456";
                         sysUser.setPassword(SecurityUtils.encryptPassword(password));
@@ -390,8 +392,9 @@
     }
 
     @Override
-    public void mobile(MobileDTO mobileDTO) {
+    public String mobile(MobileDTO mobileDTO) {
         Member byId = this.getById(mobileDTO.getMemberid());
+        String mobile=null;
         if (mobileDTO.getType()==1) {
             if (mobileDTO.getAuth_code() == null || mobileDTO.getAuth_code().length() == 0) {
             } else {
@@ -442,8 +445,7 @@
                         new TypeReference<Map<String, String>>() {
                         }, Feature.OrderedField);
 
-                byId.setPhone(openapiResult1.get("mobile"));
-                this.updateById(byId);
+                mobile=openapiResult1.get("mobile");
             }
         }else{
             String responseAccessToken = null;
@@ -469,10 +471,10 @@
             JSONObject jsonUserPhoneNumber = JSONObject.parseObject(responseUserPhoneNumber);
             String phoneInfo = jsonUserPhoneNumber.getString("phone_info");
             JSONObject jsonUserPhoneInfo = JSONObject.parseObject(phoneInfo);
-            String mobile = jsonUserPhoneInfo.getString("purePhoneNumber");
-            byId.setPhone(mobile);
-            this.updateById(byId);
+            mobile= jsonUserPhoneInfo.getString("purePhoneNumber");
+
         }
+        return mobile;
     }
 
     public static String getAccessTokenByWX() throws Exception {
diff --git a/ruoyi-modules/ruoyi-order/pom.xml b/ruoyi-modules/ruoyi-order/pom.xml
index 2e3b1ea..ced6648 100644
--- a/ruoyi-modules/ruoyi-order/pom.xml
+++ b/ruoyi-modules/ruoyi-order/pom.xml
@@ -129,7 +129,19 @@
     <dependency>
       <groupId>com.alipay.sdk</groupId>
       <artifactId>alipay-sdk-java</artifactId>
-      <version>4.39.95.ALL</version>
+      <version>4.10.167.ALL</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.github.wechatpay-apiv3</groupId>
+      <artifactId>wechatpay-java</artifactId>
+      <version>0.2.12</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.github.javen205</groupId>
+      <artifactId>IJPay</artifactId>
+      <version>1.1.9</version>
     </dependency>
 
     <dependency>
@@ -149,8 +161,12 @@
       <groupId>com.ruoyi</groupId>
       <artifactId>ruoyi-common-seata</artifactId>
     </dependency>
+
+
   </dependencies>
 
+
+
   <build>
     <finalName>${project.artifactId}</finalName>
     <plugins>
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartLogisticsController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartLogisticsController.java
index 0f5afb0..78eafc5 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartLogisticsController.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartLogisticsController.java
@@ -56,4 +56,11 @@
         wrapper.eq(Logistics::getLogisticsNum,logisticsDTO.getCompany());
         return R.ok(  iLogisticsService.getOne(wrapper));
     }
+
+    @PostMapping("/isLogisticsOne")
+    @ApiOperation(value = "用户端-获取快递是否正确")
+    public R<Boolean> isLogisticsOne(@RequestBody LogisticsDTO logisticsDTO) {
+
+        return R.ok( iLogisticsService.isLogisticsOne(logisticsDTO));
+    }
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartOrderController.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartOrderController.java
index 4533763..2eade8a 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartOrderController.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/controller/forepart/ForepartOrderController.java
@@ -66,6 +66,13 @@
         return R.ok();
     }
 
+    @PostMapping("/delOrderOne")
+    @ApiOperation(value = "用户端-删除订单")
+    public R delOrderOne(@RequestBody MemberOrderListDTO memberOrderListDTO) {
+        orderService.removeById(memberOrderListDTO.getId());
+        return R.ok();
+    }
+
     @PostMapping("/AffirmOrderOne")
     @ApiOperation(value = "用户端-确认收货订单")
     public R AffirmOrderOne(@RequestBody MemberOrderListDTO memberOrderListDTO) {
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/restTemplate/RestTemplateConfig.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/restTemplate/RestTemplateConfig.java
new file mode 100644
index 0000000..8b43a58
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/restTemplate/RestTemplateConfig.java
@@ -0,0 +1,15 @@
+package com.ruoyi.order.restTemplate;
+
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Configuration
+public class RestTemplateConfig {
+    @Bean
+    public RestTemplate restTemplate(RestTemplateBuilder builder){
+        return builder.build();
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/ILogisticsService.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/ILogisticsService.java
index 1c0f3b4..cb5f649 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/ILogisticsService.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/ILogisticsService.java
@@ -18,4 +18,6 @@
 
     Express100VO getLogisticsList(@RequestBody LogisticsDTO logisticsDTO);
 
+    Boolean isLogisticsOne(@RequestBody LogisticsDTO logisticsDTO);
+
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/LogisticsServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/LogisticsServiceImpl.java
index a681596..c789080 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/LogisticsServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/LogisticsServiceImpl.java
@@ -1,5 +1,6 @@
 package com.ruoyi.order.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.alibaba.nacos.shaded.com.google.gson.Gson;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -13,12 +14,27 @@
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.order.mapper.LogisticsMapper;
 import com.ruoyi.order.service.ILogisticsService;
+import com.ruoyi.order.vo.KuaiDiCode;
 import com.ruoyi.system.api.domain.Logistics;
 import com.ruoyi.system.api.domain.dto.LogisticsDTO;
 import com.ruoyi.system.api.domain.vo.Express100VO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 
 /**
  * <p>
@@ -35,7 +51,10 @@
     private String key="BltjQodT7186";
     private String customer="56DE8E9E3D58CE73C60755C8B7483043";
 
+    private static final String AUTONUMBER_AUTO_URL = "http://www.kuaidi100.com/autonumber/auto?num=NUM&key=KEY";
 
+    @Autowired
+    private RestTemplate restTemplate;
 
 
     @Override
@@ -67,4 +86,40 @@
         response.setLogisticsName(one.getLogisticsName());
         return response;
     }
+
+    @Override
+    public Boolean isLogisticsOne(LogisticsDTO logisticsDTO) {
+        List<KuaiDiCode> m=findKuaiDiCode(logisticsDTO.getPostid());
+        Boolean b=false;
+        if (m.size()>0){
+            for (KuaiDiCode k:m){
+               if (k.getComCode().equals(logisticsDTO.getCompany())){
+                   b=true;
+               }
+            }
+
+        }
+
+        return b;
+    }
+
+    public List<KuaiDiCode> findKuaiDiCode(String orderId) {
+        String url = AUTONUMBER_AUTO_URL.replace("NUM", orderId).replace("KEY", key);
+        // 发送快递参数处理
+        MultiValueMap<String, Object> sendBody = new LinkedMultiValueMap<>();
+        sendBody.add("num", orderId);
+        sendBody.add("key", key);
+        //设置请求头参数
+        HttpHeaders headers = new HttpHeaders();
+        headers.add("Content-type", "application/x-www-form-urlencoded");
+        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(sendBody, headers);
+        ResponseEntity<String> result = restTemplate.postForEntity(url, formEntity, String.class);
+        List<KuaiDiCode> kuaiDiCode = new ArrayList<>();
+        if (result.getBody() != null && result.getBody().length() > 0) {
+            ArrayList body = JSON.parseObject(result.getBody(), ArrayList.class);
+            body.forEach(i -> kuaiDiCode.add(JSON.parseObject(JSON.toJSONString(i), KuaiDiCode.class)));
+        }
+        return kuaiDiCode;
+    }
+
 }
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
index bd78592..5d0f6ee 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/OrderServiceImpl.java
@@ -349,6 +349,7 @@
             order.setCoverPic(goodsSku.getCoverPic());
             order.setSjPrice(goodsSku.getPrice());
         }
+        order.setOrderRemark(memberOrderDTO.getOrderRemark());
         order.setMemberId(memberOrderDTO.getMemberId());
         order.setGoodsQuantity(memberOrderDTO.getGoodsQuantity());
         order.setOrderTime(LocalDateTime.now());
@@ -406,6 +407,9 @@
     @Override
     public MemberTiOrderVO updMemberOrder(MemberOrderDTO memberOrderDTO) {
         Order order = baseMapper.selectById(memberOrderDTO.getId());
+        if(memberOrderDTO.getOrderRemark()!=null){
+            order.setOrderRemark(memberOrderDTO.getOrderRemark());
+        }
 
         MemberTiOrderVO memberOrderVO=new MemberTiOrderVO();
         if (memberOrderDTO.getReceiverDetailAddress()!=null){
@@ -515,70 +519,73 @@
 
             }
         }
-        BigDecimal pice=order.getPrice().multiply(new BigDecimal(memberOrderDTO.getGoodsQuantity()));
-        if (memberOrderDTO.getCouponId()!=null){
-            CouponMemberDTO couponMemberDTO=new CouponMemberDTO();
-            couponMemberDTO.setId(memberOrderDTO.getCouponId());
-            CouponMember data = promotionClient.getCouponMember(couponMemberDTO, SecurityConstants.INNER).getData();
-            if (order.getCouponId()!=0){
-                CouponMemberDTO couponMemberDTO1=new CouponMemberDTO();
-                couponMemberDTO1.setId(memberOrderDTO.getCouponId());
-                couponMemberDTO1.setCouponStatus(0);
-                promotionClient.updCouponMember(couponMemberDTO1, SecurityConstants.INNER);
-            }
-
-            order.setCouponId(data.getId());
-
-            if (data.getCouponType().getCode()==1){
-                if (pice.doubleValue()>=data.getFullReductionAmount().doubleValue()){
-                    pice=pice.subtract(data.getReductionAmount());
-                    order.setDiscountMoney(data.getReductionAmount());
+        if (memberOrderDTO.getGoodsQuantity()!=null){
+            BigDecimal pice=order.getPrice().multiply(new BigDecimal(memberOrderDTO.getGoodsQuantity()));
+            if (memberOrderDTO.getCouponId()!=null){
+                CouponMemberDTO couponMemberDTO=new CouponMemberDTO();
+                couponMemberDTO.setId(memberOrderDTO.getCouponId());
+                CouponMember data = promotionClient.getCouponMember(couponMemberDTO, SecurityConstants.INNER).getData();
+                if (order.getCouponId()!=0){
+                    CouponMemberDTO couponMemberDTO1=new CouponMemberDTO();
+                    couponMemberDTO1.setId(memberOrderDTO.getCouponId());
+                    couponMemberDTO1.setCouponStatus(0);
+                    promotionClient.updCouponMember(couponMemberDTO1, SecurityConstants.INNER);
                 }
-            }
-            if (data.getCouponType().getCode()==2){
-                pice= order.getTotalAmount();
-                pice=pice.subtract(data.getVoucherAmount());
-                order.setDiscountMoney(data.getVoucherAmount());
-            }
-            if (data.getCouponType().getCode()==3){
-                pice= order.getTotalAmount();
-                BigDecimal pice1=new BigDecimal(data.getDiscountRate());
-                BigDecimal pice2=new BigDecimal(0.1);
-                BigDecimal pice3=pice.multiply(pice1.multiply(pice2));
-                BigDecimal pice4= pice.subtract(pice3);
-               if (pice4.doubleValue()>data.getMaxDiscount().doubleValue()){
-                   pice=pice.subtract(data.getMaxDiscount());
-                   order.setDiscountMoney(data.getMaxDiscount());
-               }else{
-                   order.setDiscountMoney(pice4);
-                   pice=pice3;
-               }
 
+                order.setCouponId(data.getId());
+
+                if (data.getCouponType().getCode()==1){
+                    if (pice.doubleValue()>=data.getFullReductionAmount().doubleValue()){
+                        pice=pice.subtract(data.getReductionAmount());
+                        order.setDiscountMoney(data.getReductionAmount());
+                    }
+                }
+                if (data.getCouponType().getCode()==2){
+                    pice= order.getTotalAmount();
+                    pice=pice.subtract(data.getVoucherAmount());
+                    order.setDiscountMoney(data.getVoucherAmount());
+                }
+                if (data.getCouponType().getCode()==3){
+                    pice= order.getTotalAmount();
+                    BigDecimal pice1=new BigDecimal(data.getDiscountRate());
+                    BigDecimal pice2=new BigDecimal(0.1);
+                    BigDecimal pice3=pice.multiply(pice1.multiply(pice2));
+                    BigDecimal pice4= pice.subtract(pice3);
+                    if (pice4.doubleValue()>data.getMaxDiscount().doubleValue()){
+                        pice=pice.subtract(data.getMaxDiscount());
+                        order.setDiscountMoney(data.getMaxDiscount());
+                    }else{
+                        order.setDiscountMoney(pice4);
+                        pice=pice3;
+                    }
+
+                }
+                order.setCouponId(memberOrderDTO.getCouponId());
+                CouponMemberDTO couponMemberDTO2=new CouponMemberDTO();
+                couponMemberDTO2.setId(memberOrderDTO.getCouponId());
+                couponMemberDTO2.setCouponStatus(1);
+                promotionClient.updCouponMember(couponMemberDTO2, SecurityConstants.INNER);
+            }else{
+                if (order.getCouponId()!=null&&order.getCouponId()!=0){
+                    CouponMemberDTO couponMemberDTO1=new CouponMemberDTO();
+                    couponMemberDTO1.setCouponStatus(0);
+                    couponMemberDTO1.setId(order.getCouponId());
+                    promotionClient.updCouponMember(couponMemberDTO1, SecurityConstants.INNER);
+                }
+                order.setCouponId(0L);
+                order.setDiscountMoney(new BigDecimal(0));
             }
-            order.setCouponId(memberOrderDTO.getCouponId());
-            CouponMemberDTO couponMemberDTO2=new CouponMemberDTO();
-            couponMemberDTO2.setId(memberOrderDTO.getCouponId());
-            couponMemberDTO2.setCouponStatus(1);
-            promotionClient.updCouponMember(couponMemberDTO2, SecurityConstants.INNER);
-        }else{
-            if (order.getCouponId()!=null&&order.getCouponId()!=0){
-                CouponMemberDTO couponMemberDTO1=new CouponMemberDTO();
-                couponMemberDTO1.setCouponStatus(0);
-                couponMemberDTO1.setId(order.getCouponId());
-                promotionClient.updCouponMember(couponMemberDTO1, SecurityConstants.INNER);
-            }
-            order.setCouponId(0L);
-            order.setDiscountMoney(new BigDecimal(0));
+            order.setTotalAmount(pice);
+
+            CustomConfig memberPointsMoney = sysUserClient.getconfig("MEMBER_POINTS_MONEY").getData();
+            CustomConfig memberPointsPoints = sysUserClient.getconfig("MEMBER_POINTS_POINTS").getData();
+
+            Double aDouble= Double.valueOf(memberPointsMoney.getConfigValue()) * Double.valueOf(memberPointsPoints.getConfigValue());
+            BigDecimal pi=pice.multiply(new BigDecimal(aDouble));
+            order.setPoints(pi.intValue());
+            baseMapper.updateById(order);
         }
-        order.setTotalAmount(pice);
 
-        CustomConfig memberPointsMoney = sysUserClient.getconfig("MEMBER_POINTS_MONEY").getData();
-        CustomConfig memberPointsPoints = sysUserClient.getconfig("MEMBER_POINTS_POINTS").getData();
-
-        Double aDouble= Double.valueOf(memberPointsMoney.getConfigValue()) * Double.valueOf(memberPointsPoints.getConfigValue());
-        BigDecimal pi=pice.multiply(new BigDecimal(aDouble));
-        order.setPoints(pi.intValue());
-        baseMapper.updateById(order);
 
         memberOrderVO.setId(order.getId());
         memberOrderVO.setOrderStatus(OrderStatusEnum.TO_PLAY);
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java
index 55000ae..e6be77b 100644
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/PaylogServiceImpl.java
@@ -9,8 +9,9 @@
 import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jpay.ext.kit.PaymentKit;
+import com.jpay.weixin.api.WxPayApi;
 import com.ruoyi.common.core.constant.SecurityConstants;
 import com.ruoyi.common.core.domain.R;
 import com.ruoyi.common.core.enums.OrderStatusEnum;
@@ -19,8 +20,8 @@
 import com.ruoyi.order.domain.Paylog;
 import com.ruoyi.order.mapper.OrderMapper;
 import com.ruoyi.order.mapper.PaylogMapper;
-import com.ruoyi.order.service.IOrderService;
 import com.ruoyi.order.service.IPaylogService;
+import com.ruoyi.order.util.MD5AndKL;
 import com.ruoyi.order.util.SinataUtil;
 import com.ruoyi.order.util.alipay.config.AlipayConfig;
 import com.ruoyi.order.util.alipay.util.PayDemoActivity;
@@ -36,19 +37,12 @@
 import com.ruoyi.system.api.domain.dto.updMembeOneDTO;
 import com.ruoyi.system.api.feignClient.AuctionClient;
 import com.ruoyi.system.api.feignClient.MemberClient;
-import com.ruoyi.system.api.feignClient.OrderClient;
+
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.math.BigDecimal;
-import java.security.SignatureException;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -57,6 +51,7 @@
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
 
 /**
  * <p>
@@ -86,7 +81,11 @@
         String body;
         try {
             if(judgeContainsStr(orderNO)){
-                price=  Double.valueOf(1);
+                LambdaQueryWrapper<Order> wrapper1= Wrappers.lambdaQuery();
+                wrapper1.eq(Order::getOrderNo,orderNO);
+                wrapper1.eq(Order::getDelFlag,0);
+                Order page1 = OrderMapper.selectOne(wrapper1);
+                price=page1.getTotalAmount().doubleValue();
                 body = " 订单支付";
                 subject = " 订单支付";
                 Map<String, Object> map = new HashMap<String, Object>();
@@ -389,7 +388,7 @@
     public static R<Map<String, Object>> wxpay(Integer apptype, String outTradeNo, String body,String openId, Double price,
                                                HttpServletRequest request) {
         // 获取预支付接口返回参数
-        Map<String, Object> map = new HashMap<String, Object>();
+        Map<String, Object> map1 = new HashMap<String, Object>();
         Map<String, Object> appPayMap = new HashMap<String, Object>();
         try {
             // 构建接口请求参数
@@ -400,26 +399,73 @@
             System.out.println(result);
             System.out.println("WxpayController.createOrder__result:\n" + result);
             // 获取预支付接口返回参数
-            map = XMLParser.getMapFromXML(result);
+            map1 = XMLParser.getMapFromXML(result);
             System.out.println("WxpayController.createOrder__result:\n" + result);
             // 捕获预支付接口错误提示
-            if ("FAIL".equals(map.get("result_code")) || "FAIL".equals(map.get("return_code"))) {
-                return R.fail(String.valueOf(map.get("return_msg")));
+            if ("FAIL".equals(map1.get("result_code")) || "FAIL".equals(map1.get("return_code"))) {
+                return R.fail(String.valueOf(map1.get("return_msg")));
             }
 
-            // 对获取预支付返回接口参数进行封装(生成支付订单接口数据)
+      /*      // 对获取预支付返回接口参数进行封装(生成支付订单接口数据)
             AppPayReqData appPay = new AppPayReqData(apptype, (String) map.get("appid"), (String) map.get("mch_id"),
-                    (String) map.get("prepay_id"), unifiedorderReqData.getNonce_str());
+                    (String) map.get("prepay_id"), unifiedorderReqData.getNonce_str());*/
 
-                HashMap<String, Object> map1 = new HashMap<>();
-                map1.put("timeStamp", appPay.getTimestamp());
-                map1.put("nonceStr",  appPay.getNoncestr());
-                map1.put("package", "prepay_id=" +  appPay.getPrepayid());
-                map1.put("signType", "RSA");
-                map1.put("paySign", appPay.getSign());
+            UUID uuid = UUID.randomUUID();
+            String nonceStr = uuid.toString().replaceAll("-", "");
+            //商品描述 String body = "XX商城-支付订单";
+            // 创建hashmap(用户获得签名)
+            SortedMap<String, String> paraMap = new TreeMap<>();
+            //设置请求参数(小程序ID)
+            paraMap.put("appid", unifiedorderReqData.getAppid());
+            //设置请求参数(商户号)
+            paraMap.put("mch_id", unifiedorderReqData.getMch_id());
+            //设置请求参数(随机字符串)
+            paraMap.put("nonce_str", nonceStr);
+            //设置请求参数(商品描述)
+            paraMap.put("body", unifiedorderReqData.getBody());
+            //设置请求参数(商户订单号)
+            paraMap.put("out_trade_no", unifiedorderReqData.getOut_trade_no());
+            //设置请求参数(总金额)
+            paraMap.put("total_fee", unifiedorderReqData.getTotal_fee().toString());
+            //设置请求参数(通知地址)
+            paraMap.put("notify_url", unifiedorderReqData.getNotify_url());
+            //设置请求参数(交易类型)
+            paraMap.put("trade_type", String.valueOf(WxPayApi.TradeType.JSAPI));
 
+            paraMap.put("openid", unifiedorderReqData.getOpenid());
+
+            //设置请求参数(openid)(在接口文档中 该参数 是否必填项 但是一定要注意 如果交易类型设置成'JSAPI'则必须传入openid)
+            //MD5运算生成签名,这里是第一次签名,用于调用统一下单接口
+            String sign = PaymentKit.createSign(paraMap, "E10ADC3949BA59ABBE56E057F20F883E");
+            paraMap.put("sign", sign);
+            //统一下单,向微信api发送数据
+            //转成xml
+            String xmlResult = WxPayApi.pushOrder(false, paraMap);
+            Map<String, String> map = PaymentKit.xmlToMap(xmlResult);
+            //返回状态码
+            String returnCode = map.get("return_code");
+      /*      Assert.isTrue("SUCCESS".equals(returnCode), getMsgByCode(returnCode));*/
+
+            //返回给小程序端需要的参数
+            Map<String, Object> returnMap = new HashMap<>(20);
+
+            String prepay_id = map.get("prepay_id");
+            //重新进行签名后返回给前端
+            returnMap.put("appId", map.get("appid"));
+            returnMap.put("nonceStr", map.get("nonce_str"));
+            returnMap.put("package", "prepay_id=" + prepay_id);
+            returnMap.put("timeStamp", new Date().getTime() + "");
+            returnMap.put("signType", "MD5");
+            String signature = weixinSignature(returnMap, "E10ADC3949BA59ABBE56E057F20F883E");
+
+            returnMap.put("prepay_id", prepay_id);
+            returnMap.put("mch_id", map.get("mch_id"));
+            returnMap.put("trade_type", map.get("trade_type"));
+
+            returnMap.put("sign", signature);
+            returnMap.put("err_code_des", map.get("err_code_des"));
             // 对获取预支付返回接口参数进行封装(生成支付订单接口数据)
-            return R.ok(map1);
+            return R.ok(returnMap);
         } catch (Exception e) {
             System.out.println("统一下单_API_处理异常!");
             e.printStackTrace();
@@ -427,6 +473,36 @@
         return R.fail("统一下单失败");
     }
 
+    private static String weixinSignature(Map<String, Object> map, String privateKey) {
+        try {
+            Set<Map.Entry<String, Object>> entries = map.entrySet();
+            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
+            // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
+            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
+                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+                    return (o1.getKey()).toString().compareTo(o2.getKey());
+                }
+            });
+            // 构造签名键值对的格式
+            StringBuilder sb = new StringBuilder();
+            for (Map.Entry<String, Object> item : infoIds) {
+                if (item.getKey() != null || item.getKey() != "") {
+                    String key = item.getKey();
+                    Object val = item.getValue();
+                    if (!(val == "" || val == null)) {
+                        sb.append(key + "=" + val + "&");
+                    }
+                }
+            }
+            sb.append("key=" + privateKey);
+            String sign = MD5AndKL.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); //注:MD5签名方式
+            return sign;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
 
 
     /**
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/MD5AndKL.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/MD5AndKL.java
new file mode 100644
index 0000000..72cdae6
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/MD5AndKL.java
@@ -0,0 +1,116 @@
+package com.ruoyi.order.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.security.MessageDigest;
+
+public class MD5AndKL {
+
+    private static Logger logger = LoggerFactory.getLogger(MD5AndKL.class);
+
+    /**
+     * MD5加码。32位
+     *
+     * @param inStr
+     * @return
+     */
+    public static String MD5(String inStr) {
+        MessageDigest md5 = null;
+        try {
+            md5 = MessageDigest.getInstance("MD5");
+        } catch (Exception e) {
+            throw new RuntimeException(e.toString());
+        }
+        byte[] md5Bytes = md5.digest(inStr.getBytes());
+        StringBuffer hexValue = new StringBuffer();
+        for (int i = 0; i < md5Bytes.length; i++) {
+            int val = ((int) md5Bytes[i]) & 0xff;
+            if (val < 16) {
+                hexValue.append("0");
+            }
+            hexValue.append(Integer.toHexString(val));
+        }
+        return hexValue.toString();
+    }
+
+    /**
+     * 可逆的加密算法
+     *
+     * @param inStr
+     * @return
+     */
+    public static String KL(String inStr) {
+        char[] a = inStr.toCharArray();
+        for (int i = 0; i < a.length; i++) {
+            a[i] = (char) (a[i] ^ 't');
+        }
+        String s = new String(a);
+        return s;
+    }
+
+    /**
+     * 加密后解密
+     *
+     * @param inStr
+     * @return
+     */
+    public static String JM(String inStr) {
+        char[] a = inStr.toCharArray();
+        for (int i = 0; i < a.length; i++) {
+            a[i] = (char) (a[i] ^ 't');
+        }
+        String k = new String(a);
+        return k;
+    }
+
+
+    private static String byteArrayToHexString(byte b[]) {
+        StringBuffer resultSb = new StringBuffer();
+        for (int i = 0; i < b.length; i++)
+            resultSb.append(byteToHexString(b[i]));
+
+        return resultSb.toString();
+    }
+
+    private static String byteToHexString(byte b) {
+        int n = b;
+        if (n < 0)
+            n += 256;
+        int d1 = n / 16;
+        int d2 = n % 16;
+        return hexDigits[d1] + hexDigits[d2];
+    }
+
+    public static String MD5Encode(String origin, String charsetname) {
+        String resultString = null;
+        try {
+            resultString = new String(origin);
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            if (charsetname == null || "".equals(charsetname)) {
+                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
+            } else {
+                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
+            }
+        } catch (Exception exception) {
+            exception.printStackTrace();
+        }
+        return resultString;
+    }
+
+    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
+
+    public static void main(String args[]) {
+
+        logger.debug("MD5后再加密:" + KL(MD5("123456")));
+        logger.debug(MD5("123456"));
+        // logger.debug("加密:" + KL(MD5("123456")));
+        // s = KL(s);
+        // logger.debug("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
+        // logger.debug("解密:" + JM(KL(s)));
+        // logger.debug("解密为MD5后的:" + KL(KL(MD5(s))));
+        // logger.debug(JM("5d62957bb57d3e49dcf48a0df064be4c"));
+        // logger.debug(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ToolUtil.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ToolUtil.java
new file mode 100644
index 0000000..c5ad01c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/ToolUtil.java
@@ -0,0 +1,718 @@
+/**
+ * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ruoyi.order.util;
+
+import com.google.gson.Gson;
+import com.ruoyi.common.core.utils.DateUtils;
+import com.ruoyi.order.util.support.StrKit;
+
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Array;
+import java.math.BigDecimal;
+import java.net.URISyntaxException;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * 高频方法集合类
+ */
+public class ToolUtil {
+
+    /**
+     * 获取随机位数的字符串
+     *
+     * @author fengshuonan
+     * @Date 2017/8/24 14:09
+     */
+    public static String getRandomString(int length) {
+        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
+        Random random = new Random();
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            int number = random.nextInt(base.length());
+            sb.append(base.charAt(number));
+        }
+        return sb.toString();
+    }
+
+    public static <T> T objFromJson(Object src, Class<T> classOfT) {
+        Gson gson = new Gson();
+        return gson.fromJson(gson.toJson(src), classOfT);
+    }
+
+    /**
+     * 获取随机位数数字串
+     */
+    public static String getRandomNumber(int length) {
+        String base = "0123456789";
+        Random random = new Random();
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < length; i++) {
+            int number = random.nextInt(base.length());
+            sb.append(base.charAt(number));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 判断一个对象是否是时间类型
+     *
+     * @author stylefeng
+     * @Date 2017/4/18 12:55
+     */
+  /*  public static String dateType(Object o) {
+        if (o instanceof Date) {
+            return DateUtils.getDay((Date) o);
+        } else {
+            return o.toString();
+        }
+    }*/
+
+    /**
+     * 获取异常的具体信息
+     *
+     * @author fengshuonan
+     * @Date 2017/3/30 9:21
+     * @version 2.0
+     */
+    public static String getExceptionMsg(Exception e) {
+        StringWriter sw = new StringWriter();
+        try {
+            e.printStackTrace(new PrintWriter(sw));
+        } finally {
+            try {
+                sw.close();
+            } catch (IOException e1) {
+                e1.printStackTrace();
+            }
+        }
+        return sw.getBuffer().toString().replaceAll("\\$", "T");
+    }
+
+    /**
+     * 比较两个对象是否相等。<br>
+     * 相同的条件有两个,满足其一即可:<br>
+     * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
+     *
+     * @param obj1 对象1
+     * @param obj2 对象2
+     * @return 是否相等
+     */
+    public static boolean equals(Object obj1, Object obj2) {
+        return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
+    }
+
+    /**
+     * 计算对象长度,如果是字符串调用其length函数,集合类调用其size函数,数组调用其length属性,其他可遍历对象遍历计算长度
+     *
+     * @param obj 被计算长度的对象
+     * @return 长度
+     */
+    public static int length(Object obj) {
+        if (obj == null) {
+            return 0;
+        }
+        if (obj instanceof CharSequence) {
+            return ((CharSequence) obj).length();
+        }
+        if (obj instanceof Collection) {
+            return ((Collection<?>) obj).size();
+        }
+        if (obj instanceof Map) {
+            return ((Map<?, ?>) obj).size();
+        }
+
+        int count;
+        if (obj instanceof Iterator) {
+            Iterator<?> iter = (Iterator<?>) obj;
+            count = 0;
+            while (iter.hasNext()) {
+                count++;
+                iter.next();
+            }
+            return count;
+        }
+        if (obj instanceof Enumeration) {
+            Enumeration<?> enumeration = (Enumeration<?>) obj;
+            count = 0;
+            while (enumeration.hasMoreElements()) {
+                count++;
+                enumeration.nextElement();
+            }
+            return count;
+        }
+        if (obj.getClass().isArray() == true) {
+            return Array.getLength(obj);
+        }
+        return -1;
+    }
+
+    /**
+     * 对象中是否包含元素
+     *
+     * @param obj     对象
+     * @param element 元素
+     * @return 是否包含
+     */
+    public static boolean contains(Object obj, Object element) {
+        if (obj == null) {
+            return false;
+        }
+        if (obj instanceof String) {
+            if (element == null) {
+                return false;
+            }
+            return ((String) obj).contains(element.toString());
+        }
+        if (obj instanceof Collection) {
+            return ((Collection<?>) obj).contains(element);
+        }
+        if (obj instanceof Map) {
+            return ((Map<?, ?>) obj).values().contains(element);
+        }
+
+        if (obj instanceof Iterator) {
+            Iterator<?> iter = (Iterator<?>) obj;
+            while (iter.hasNext()) {
+                Object o = iter.next();
+                if (equals(o, element)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        if (obj instanceof Enumeration) {
+            Enumeration<?> enumeration = (Enumeration<?>) obj;
+            while (enumeration.hasMoreElements()) {
+                Object o = enumeration.nextElement();
+                if (equals(o, element)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+        if (obj.getClass().isArray() == true) {
+            int len = Array.getLength(obj);
+            for (int i = 0; i < len; i++) {
+                Object o = Array.get(obj, i);
+                if (equals(o, element)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 对象是否不为空(新增)
+     */
+    public static boolean isNotEmpty(Object o) {
+        return !isEmpty(o);
+    }
+
+    /**
+     * 对象是否为空
+     */
+    @SuppressWarnings("rawtypes")
+    public static boolean isEmpty(Object o) {
+        if (o == null) {
+            return true;
+        }
+        if (o instanceof String) {
+            if (o.toString().trim().equals("")) {
+                return true;
+            }
+        } else if (o instanceof List) {
+            if (((List) o).size() == 0) {
+                return true;
+            }
+        } else if (o instanceof Map) {
+            if (((Map) o).size() == 0) {
+                return true;
+            }
+        } else if (o instanceof Set) {
+            if (((Set) o).size() == 0) {
+                return true;
+            }
+        } else if (o instanceof Object[]) {
+            if (((Object[]) o).length == 0) {
+                return true;
+            }
+        } else if (o instanceof int[]) {
+            if (((int[]) o).length == 0) {
+                return true;
+            }
+        } else if (o instanceof long[]) {
+            if (((long[]) o).length == 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 对象组中是否存在 Empty Object
+     *
+     * @param os 对象组
+     * @return
+     */
+    public static boolean isOneEmpty(Object... os) {
+        for (Object o : os) {
+            if (isEmpty(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 对象组中是否全是 Empty Object
+     *
+     * @param os
+     * @return
+     */
+    public static boolean isAllEmpty(Object... os) {
+        for (Object o : os) {
+            if (!isEmpty(o)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 是否为数字
+     *
+     * @param obj
+     * @return
+     */
+    public static boolean isNum(Object obj) {
+        try {
+            Integer.parseInt(obj.toString());
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 如果为空, 则调用默认值
+     *
+     * @param str
+     * @return
+     */
+    public static Object getValue(Object str, Object defaultValue) {
+        if (isEmpty(str)) {
+            return defaultValue;
+        }
+        return str;
+    }
+
+    /**
+     * 格式化文本
+     *
+     * @param template 文本模板,被替换的部分用 {} 表示
+     * @param values   参数值
+     * @return 格式化后的文本
+     */
+    public static String format(String template, Object... values) {
+        return StrKit.format(template, values);
+    }
+
+    /**
+     * 格式化文本
+     *
+     * @param template 文本模板,被替换的部分用 {key} 表示
+     * @param map      参数值对
+     * @return 格式化后的文本
+     */
+    public static String format(String template, Map<?, ?> map) {
+        return StrKit.format(template, map);
+    }
+
+    /**
+     * 强转->string,并去掉多余空格
+     *
+     * @param str
+     * @return
+     */
+    public static String toStr(Object str) {
+        return toStr(str, "");
+    }
+
+    /**
+     * 强转->string,并去掉多余空格
+     *
+     * @param str
+     * @param defaultValue
+     * @return
+     */
+    public static String toStr(Object str, String defaultValue) {
+        if (null == str) {
+            return defaultValue;
+        }
+        return str.toString().trim();
+    }
+
+    /**
+     * 强转->int
+     *
+     * @param obj
+     * @return
+     */
+//	public static int toInt(Object value) {
+//		return toInt(value, -1);
+//	}
+
+    /**
+     * 强转->int
+     *
+     * @param obj
+     * @param defaultValue
+     * @return
+     */
+//	public static int toInt(Object value, int defaultValue) {
+//		return Convert.toInt(value, defaultValue);
+//	}
+
+    /**
+     * 强转->long
+     *
+     * @param obj
+     * @return
+     */
+//	public static long toLong(Object value) {
+//		return toLong(value, -1);
+//	}
+
+    /**
+     * 强转->long
+     *
+     * @param obj
+     * @param defaultValue
+     * @return
+     */
+//	public static long toLong(Object value, long defaultValue) {
+//		return Convert.toLong(value, defaultValue);
+//	}
+//
+//	public static String encodeUrl(String url) {
+//		return URLKit.encode(url, CharsetKit.UTF_8);
+//	}
+//
+//	public static String decodeUrl(String url) {
+//		return URLKit.decode(url, CharsetKit.UTF_8);
+//	}
+
+    /**
+     * map的key转为小写
+     *
+     * @param map
+     * @return Map<String, Object>
+     */
+    public static Map<String, Object> caseInsensitiveMap(Map<String, Object> map) {
+        Map<String, Object> tempMap = new HashMap<>();
+        for (String key : map.keySet()) {
+            tempMap.put(key.toLowerCase(), map.get(key));
+        }
+        return tempMap;
+    }
+
+    /**
+     * 获取map中第一个数据值
+     *
+     * @param <K> Key的类型
+     * @param <V> Value的类型
+     * @param map 数据源
+     * @return 返回的值
+     */
+    public static <K, V> V getFirstOrNull(Map<K, V> map) {
+        V obj = null;
+        for (Entry<K, V> entry : map.entrySet()) {
+            obj = entry.getValue();
+            if (obj != null) {
+                break;
+            }
+        }
+        return obj;
+    }
+
+    /**
+     * 创建StringBuilder对象
+     *
+     * @return StringBuilder对象
+     */
+    public static StringBuilder builder(String... strs) {
+        final StringBuilder sb = new StringBuilder();
+        for (String str : strs) {
+            sb.append(str);
+        }
+        return sb;
+    }
+
+    /**
+     * 创建StringBuilder对象
+     *
+     * @return StringBuilder对象
+     */
+    public static void builder(StringBuilder sb, String... strs) {
+        for (String str : strs) {
+            sb.append(str);
+        }
+    }
+
+    /**
+     * 去掉指定后缀
+     *
+     * @param str    字符串
+     * @param suffix 后缀
+     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
+     */
+    public static String removeSuffix(String str, String suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return str;
+        }
+
+        if (str.endsWith(suffix)) {
+            return str.substring(0, str.length() - suffix.length());
+        }
+        return str;
+    }
+
+    /**
+     * 当前时间
+     *
+     * @author stylefeng
+     * @Date 2017/5/7 21:56
+     */
+    public static String currentTime() {
+        return DateUtils.getTime();
+    }
+
+    /**
+     * 首字母大写
+     *
+     * @author stylefeng
+     * @Date 2017/5/7 22:01
+     */
+    public static String firstLetterToUpper(String val) {
+        return StrKit.firstCharToUpperCase(val);
+    }
+
+    /**
+     * 首字母小写
+     *
+     * @author stylefeng
+     * @Date 2017/5/7 22:02
+     */
+    public static String firstLetterToLower(String val) {
+        return StrKit.firstCharToLowerCase(val);
+    }
+
+    /**
+     * 判断是否是windows操作系统
+     *
+     * @author stylefeng
+     * @Date 2017/5/24 22:34
+     */
+    public static Boolean isWinOs() {
+        String os = System.getProperty("os.name");
+        if (os.toLowerCase().startsWith("win")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 获取临时目录
+     *
+     * @author stylefeng
+     * @Date 2017/5/24 22:35
+     */
+    public static String getTempPath() {
+        return System.getProperty("java.io.tmpdir");
+    }
+
+    /**
+     * 把一个数转化为int
+     *
+     * @author fengshuonan
+     * @Date 2017/11/15 下午11:10
+     */
+    public static Integer toInt(Object val) {
+        if (val instanceof Double) {
+            BigDecimal bigDecimal = new BigDecimal((Double) val);
+            return bigDecimal.intValue();
+        } else {
+            return Integer.valueOf(val.toString());
+        }
+
+    }
+
+    /**
+     * 获取项目路径
+     */
+    public static String getWebRootPath(String filePath) {
+        try {
+            String path = ToolUtil.class.getClassLoader().getResource("").toURI().getPath();
+            path = path.replace("/WEB-INF/classes/", "");
+            path = path.replace("/target/classes/", "");
+            path = path.replace("file:/", "");
+            if (ToolUtil.isEmpty(filePath)) {
+                return path;
+            } else {
+                return path + "/" + filePath;
+            }
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取文件后缀名 不包含点
+     */
+    public static String getFileSuffix(String fileWholeName) {
+        if (ToolUtil.isEmpty(fileWholeName)) {
+            return "none";
+        }
+        int lastIndexOf = fileWholeName.lastIndexOf(".");
+        return fileWholeName.substring(lastIndexOf + 1);
+    }
+
+    /**
+     * 逗号拼接字符串
+     */
+    public static String commaSpliceString(String first, String second, Object... param) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(first + "," + second);
+        if (param != null) {
+            for (int i = 0; i < param.length; i++) {
+                sb.append("," + param[i]);
+            }
+        }
+        return sb.toString();
+    }
+
+    /**
+     * List列表去重
+     */
+    public static List listRemoveDuplicate(List list) {
+        HashSet h = new HashSet(list);
+        list.clear();
+        list.addAll(h);
+        return list;
+    }
+
+    /**
+     * H5页面代码包装(判断加上自适应代码)
+     */
+    public static String h5Warpper(String h5Code) {
+        String warpper = "<meta name=\"viewport\" content=\"width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no\"/>";
+        // 代码不包含自适应代码,前部追加代码
+        if (!h5Code.contains(warpper)) {
+            return warpper + h5Code;
+        }
+        return h5Code;
+    }
+
+    /**
+     * 字符串Base64位加密
+     */
+    public static String Base64Encode(String src) {
+        return new String(Base64.getEncoder().encode(src.getBytes()));
+    }
+
+    /**
+     * 字符串Base64位解密
+     */
+    public static String Base64Decode(String src) {
+        return new String(Base64.getDecoder().decode(src.getBytes()));
+    }
+
+    /**
+     * 排序签名:通常需要签名和验签,而签名时,需要对url内容进行排序。
+     */
+    public static String putPairsSequenceAndTogether(Map<String, String> info) {
+        List<Entry<String, String>> infoIds = new ArrayList<Entry<String, String>>(info.entrySet());
+        Collections.sort(infoIds, new Comparator<Entry<String, String>>() {
+            @Override
+            public int compare(Entry<String, String> arg0, Entry<String, String> arg1) {
+                // TODO Auto-generated method stub
+                return (arg0.getKey()).compareTo(arg1.getKey());
+            }
+        });
+        String ret = "";
+        for (Entry<String, String> entry : infoIds) {
+            ret += entry.getKey();
+            ret += "=";
+            ret += entry.getValue();
+            ret += "&";
+        }
+        ret = ret.substring(0, ret.length() - 1);
+        return ret;
+    }
+
+    /**
+     * 将Map封装为Url参数串
+     */
+    public static String getUrlParmStr(Map<String, Object> map) {
+        StringBuffer sb = new StringBuffer();
+        for (Entry<String, Object> entry : map.entrySet()) {
+            sb.append(entry.getKey());
+            sb.append("=");
+            sb.append(entry.getValue());
+            sb.append("&");
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 获取客户端真实IP地址
+     */
+    public static String getIpAddress(HttpServletRequest request) {
+        // 避免反向代理不能获取真实地址, 取X-Forwarded-For中第一个非unknown的有效IP字符串
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        return ip;
+    }
+
+    /**
+     * 字符串转对象
+     *
+     * @param str      字符串
+     * @param classOfT 转换后对象类
+     * @param <T>      转换后对象
+     * @return
+     */
+    public static <T> T fromJson(String str, Class<T> classOfT) {
+        Gson gson = new Gson();
+        return gson.fromJson(str, classOfT);
+    }
+
+}
\ No newline at end of file
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/WxPayUtils.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/WxPayUtils.java
deleted file mode 100644
index 2583d2f..0000000
--- a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/WxPayUtils.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-package com.ruoyi.order.util;
-
-import cn.hutool.http.HttpRequest;
-import cn.hutool.json.JSONObject;
-import cn.hutool.json.JSONUtil;
-
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
-import java.security.*;
-import java.util.*;
-
-
-public class WxPayUtils {
-    public static final String serial_no = "xxx";
-    // 商户号
-    public static final String mchId = "xxx";
-    // appid
-    public static final String appId = "xxx";
-
-    // 证书私钥
-    public static final String privateKey = "-----BEGIN PRIVATE KEY-----\n" +
-            "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDBJn3bVt9BbLhs\n" +
-            "+ZjULV7Odh4rtBBd2wc7uZ8RlN/9E8sJfAefowiSTPwOkTYKDlyhpG131a4VKj+N\n" +
-            "zaTu0Y5zQGyl29ElHVVuPw4mVni7xyqVdJ5VUxyJMKHmQsGpngHS4sF28c5Aihfi\n" +
-            "Gkydt6BRF8xwFC9u+D0r4PY9dwHTn4jyaFd25CMUxVO+rfjOWFuGa/rEjtQw03KU\n" +
-            "UVR6np6FmNXdWalQbmbETyUqGjCac6J7hDZ1LIRU4YtqMqqsXhnk3FaoS23MOgaZ\n" +
-            "RE3nIgpYqGgfXfLOKDt5n4zLALJkV0xmk3VErbheWpzRVFae/JMtsf/8ySgtiOga\n" +
-            "n8fvShJNAgMBAAECggEAf+P+vbb9yJI2Y2G5QfRwrAAl5gYqOBsI5RD5NGkBDs+G\n" +
-            "RtdrLNaEnGqBExwvTeVIjHcVTJ2d0MHSpxAdP0xeKA3mYsPz7cFIieESe2wSMTOl\n" +
-            "DKTVGeYYJPagnJhjJu5KgtpGA34EdVN6kOmdBWlKq6c4ZJXY+n8/8cfZA8XC3d3B\n" +
-            "favo104podp8cC2IVNMs21OzbjD4V+6VV9X/5BA6x7bDcarlJXSyCehdXgjhjNmT\n" +
-            "/9gz7MFhOsUlAG7P03easIRcZCQL6z9MebD3xfVYcXnS4L3CcVw1FWEdLXxe/3IG\n" +
-            "Q8UPTPHhTLFRbURHI00x1jEvcD9qKXYgKeU/N7IY+QKBgQD93r2SotKM5EDxM3L2\n" +
-            "5UFrmEVnf4bwg5QDyZFpjAJ+/uMSsEX3f1m8Mst82Y4Mybz8XVMNsUJmoY8eJoM+\n" +
-            "sqRbI5HXySsFEbDqh7jrtBoN7R1rl3jQw4qxqWYR8GQJ6VqAXuEFbrxgE1YFgqw5\n" +
-            "40HAYbv417h0h5A1rcRKegoW9wKBgQDCxVaCmBzcYYFc2leRy6qH965OEedqbSCV\n" +
-            "QPprCDBoBM6jrq97ZfWyfmLNSjjFhTSz9h8z5dQcePZrrI3+evlE8V18hUmWN6rM\n" +
-            "CvPCb+4q8CwiHmLFqVp+m11MR8EOBcWCW/HlioqBKTLglijY53RUjW7No/T+32sf\n" +
-            "5R1qYq672wKBgQC3dztFN4o169bK+UWCDBgFK9wsecsJEe3r9sWxo09Ce+2aWe2W\n" +
-            "eWBeU88fARJZR4neT4tv/8Re6y7EuUxsCSoh+0iwy17doPVb6I3JOTUDD3MNiD/1\n" +
-            "jvsyfZuYJ0QErbGLyAWSqX5VaGPoQ5E3nHauE3OG2E8jV7zuLhAHSr7z7QKBgAF8\n" +
-            "Z/CPIIk95TLEJ67hEuf+p8HIuS9CreD1ofN3GIdyofD1wDj8yicWd8KBMnWvUnud\n" +
-            "ARfwRPICqj6gDmVGoug3vzLYAXu36QGtg7aUDAkf0/ZerPo9FIeqv8d5NKvat2sL\n" +
-            "MIlDyVK68bxs6NreyTBr89B108SuB68ynErXfeXJAoGBAMCoJyWdFAQKVvycHyv4\n" +
-            "914+v7niQahws23wxHlzvup8/doCS1XVQAoEyQ4iIPDHYmiOCcmzCQnb1CWgMbIl\n" +
-            "oBY3baP1GWOwEWw/HYKOwHW3fLkYC/xaRi+b5IxyEzR7hlCm/A6gCnCUYqIdU8gd\n" +
-            "jYE4kGB2O/5vdbITdSMai47o\n" +
-            "-----END PRIVATE KEY-----";
-
-
-    */
-/**
-     * 获取微信预支付订单号
-     * @return
-     *//*
-
-    public JSONObject getPrepayId(Integer apptype, String outTradeNo, String body1,String openId, Double price){
-
-        JSONObject jsonObject = new JSONObject();
-        JSONObject amountJsonObject = new JSONObject();
-        JSONObject payerJsonObject = new JSONObject();
-        amountJsonObject.put("total",price);
-        payerJsonObject.put("openid",openId);
-        // 应用ID
-        jsonObject.put("appid",appId);
-        // 商户号
-        jsonObject.put("mchid",mchId);
-        // 商品描述
-        jsonObject.put("description",body1);
-        // 商户订单号
-        jsonObject.put("out_trade_no",outTradeNo);
-        // 通知地址
-        jsonObject.put("notify_url","https://zc.xxx.com/wx/api/pay/notifyUrl");
-        // 订单金额信息
-        jsonObject.put("amount",amountJsonObject);
-        // 支付者信息
-        jsonObject.put("payer",payerJsonObject);
-        String body = jsonObject.toString();
-        System.out.println(body);
-        String authorization = signStr("POST", "/v3/pay/transactions/jsapi", body);
-
-        String result = HttpRequest.post("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi")
-                .body(body)
-                .header("Content-Type","application/json")
-                .header("Accept","application/json")
-                .header("Authorization","WECHATPAY2-SHA256-RSA2048 " + authorization)//头信息,多个头信息多次调用此方法即可
-                .timeout(10000)//超时,毫秒
-                .execute().body();
-        JSONObject jsonObject1 = JSONUtil.parseObj(result);
-        String prepay_id = jsonObject1 == null ? "":(String) jsonObject1.get("prepay_id");
-        JSONObject resultJsonObject = new JSONObject();
-        resultJsonObject.put("prepay_id",prepay_id);
-        resultJsonObject.put("chatPrice",wxOrder.getTotalPrice());
-        return resultJsonObject;
-    }
-
-    */
-/**
-     * 成功获取微信预支付订单号后, 返回给前端调起微信支付的必要参数
-     * @param orderNo   商户订单号
-     * @param prepay_id 预支付订单号
-     * @return
-     *//*
-
-    public Map<String, Object> returnToReceptionJson(String orderNo, String prepay_id){
-        HashMap<String, Object> map = new HashMap<>();
-        long timeStamp = System.currentTimeMillis() / 1000;
-        String uuid = UUID.randomUUID().toString().replace("-", "");
-        String paySign = getPaySign(timeStamp, uuid, prepay_id);
-        map.put("orderId", orderNo);
-        map.put("timeStamp", timeStamp);
-        map.put("nonceStr", uuid);
-        map.put("package", "prepay_id=" + prepay_id);
-        map.put("signType", "RSA");
-        map.put("paySign", paySign);
-        return map;
-    }
-
-    public String getPaySign(long timestamp, String randString, String prepay_id){
-        String data =  appId + "\n" +
-                timestamp + "\n" +
-                randString + "\n" +
-                "prepay_id=" + prepay_id + "\n";
-        String signature = null;
-        try {
-            signature = sign(data.getBytes("utf-8"));
-        } catch (SignatureException e) {
-            e.printStackTrace();
-        } catch (UnsupportedEncodingException e) {
-            e.printStackTrace();
-        }
-        return signature;
-    }
-
-    public String signStr2(String method, String url){
-        String nonceStr = UUID.randomUUID().toString();
-        long timestamp = System.currentTimeMillis() / 1000;
-        String message = buildMessage2(method, url, timestamp, nonceStr);
-        String signature = null;
-        try {
-            signature = sign(message.getBytes("utf-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        System.out.println("签名后:[" + signature + "]");
-        return  "mchid=\"" + mchId + "\","
-                + "serial_no=\"" + serial_no + "\","
-                + "nonce_str=\"" + nonceStr + "\","
-                + "timestamp=\"" + timestamp + "\","
-                + "signature=\"" + signature + "\"";
-    }
-
-    public String buildMessage2(String method, String url, long timestamp, String nonceStr) {
-        String str = method + "\n"
-                + url + "\n"
-                + timestamp + "\n"
-                + nonceStr + "\n\n";
-        System.out.println("签名数据[" + str + "]");
-        return str;
-    }
-
-    public String signStr(String method, String url, String body){
-        String nonceStr = UUID.randomUUID().toString();
-        long timestamp = System.currentTimeMillis() / 1000;
-        String message = buildMessage(method, url, timestamp, nonceStr, body);
-        System.out.println("message:[" + message + "]");
-        String signature = null;
-        try {
-            signature = sign(message.getBytes("utf-8"));
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        System.out.println("signature=[" + signature + "]");
-        return  "mchid=\"" + mchId + "\","
-                + "nonce_str=\"" + nonceStr + "\","
-                + "timestamp=\"" + timestamp + "\","
-                + "serial_no=\"" + serial_no + "\","
-                + "signature=\"" + signature + "\"";
-    }
-
-    public String buildMessage(String method, String url, long timestamp, String nonceStr, String body) {
-        String str = method + "\n"
-                + url + "\n"
-                + timestamp + "\n"
-                + nonceStr + "\n"
-                + body + "\n";
-        return str;
-    }
-
-    public String sign(byte[] message) throws Exception {
-        Signature sign = null;
-        try {
-            sign = Signature.getInstance("SHA256withRSA");
-            PrivateKey privateKey = getPrivateKey();
-            sign.initSign(privateKey);
-            sign.update(message);
-        } catch (NoSuchAlgorithmException e) {
-            e.printStackTrace();
-        } catch (SignatureException e) {
-            e.printStackTrace();
-        } catch (InvalidKeyException e) {
-            e.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        return Base64.getEncoder().encodeToString(sign.sign());
-    }
-    */
-/**
-     * 获取私钥。
-     *//*
-
-    public static PrivateKey getPrivateKey() throws IOException {
-        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(
-                new ByteArrayInputStream(privateKey.getBytes("utf-8")));
-        return merchantPrivateKey;
-    }
-
-    // xml解析
-    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
-        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");
-        if(null == strxml || "".equals(strxml)) {
-            return null;
-        }
-        Map m = new HashMap();
-        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
-        SAXBuilder builder = new SAXBuilder();
-        Document doc = builder.build(in);
-        Element root = doc.getRootElement();
-        List list = root.getChildren();
-        Iterator it = list.iterator();
-        while(it.hasNext()) {
-            Element e = (Element) it.next();
-            String k = e.getName();
-            String v = "";
-            List children = e.getChildren();
-            if(children.isEmpty()) {
-                v = e.getTextNormalize();
-            } else {
-                v = getChildrenText(children);
-            }
-            m.put(k, v);
-        }
-        //关闭流
-        in.close();
-        return m;
-    }
-
-    */
-/**
-     * 获取子结点的xml
-     *
-     * @param children
-     * @return String
-     *//*
-
-    public static String getChildrenText(List children) {
-        StringBuffer sb = new StringBuffer();
-        if(!children.isEmpty()) {
-            Iterator it = children.iterator();
-            while(it.hasNext()) {
-                Element e = (Element) it.next();
-                String name = e.getName();
-                String value = e.getTextNormalize();
-                List list = e.getChildren();
-                sb.append("<" + name + ">");
-                if(!list.isEmpty()) {
-                    sb.append(getChildrenText(list));
-                }
-                sb.append(value);
-                sb.append("</" + name + ">");
-            }
-        }
-        return sb.toString();
-    }
-}
-*/
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/JwtProperties.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/JwtProperties.java
new file mode 100644
index 0000000..918844e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/JwtProperties.java
@@ -0,0 +1,71 @@
+package com.ruoyi.order.util.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * jwt相关配置
+ *
+ * @author fengshuonan
+ * @date 2017-08-23 9:23
+ */
+@Configuration
+@ConfigurationProperties(prefix = JwtProperties.JWT_PREFIX)
+public class JwtProperties {
+
+    public static final String JWT_PREFIX = "jwt";
+
+    private String header = "Authorization";
+
+    private String secret = "defaultSecret";
+
+    private Long expiration = 604800L;
+
+    private String authPath = "auth";
+
+    private String md5Key = "randomKey";
+
+    public static String getJwtPrefix() {
+        return JWT_PREFIX;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public void setHeader(String header) {
+        this.header = header;
+    }
+
+    public String getSecret() {
+        return secret;
+    }
+
+    public void setSecret(String secret) {
+        this.secret = secret;
+    }
+
+    public Long getExpiration() {
+        return expiration;
+    }
+
+    public void setExpiration(Long expiration) {
+        this.expiration = expiration;
+    }
+
+    public String getAuthPath() {
+        return authPath;
+    }
+
+    public void setAuthPath(String authPath) {
+        this.authPath = authPath;
+    }
+
+    public String getMd5Key() {
+        return md5Key;
+    }
+
+    public void setMd5Key(String md5Key) {
+        this.md5Key = md5Key;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/PayProperties.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/PayProperties.java
new file mode 100644
index 0000000..a92b104
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/PayProperties.java
@@ -0,0 +1,74 @@
+package com.ruoyi.order.util.properties;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+
+/**
+ * 配置参数
+ *
+ * @author: KingKong
+ * @create: 2018-12-17 14:36
+ **/
+@Data
+@Component
+@Configuration
+@ConfigurationProperties(prefix = "pay")
+public class PayProperties {
+
+    /**
+     * 应用私钥
+     */
+    private String aliPrivateKey;
+    /**
+     * 支付宝公钥(不是应用公钥)
+     */
+    private String aliPublicKey;
+    private String aliAppId;
+    private String aliNotifyUrl;
+    private String aliReturnUrl;
+    /**
+     * 支付宝账号
+     */
+    private String aliSellerId;
+
+
+    /**
+     * 微信appId
+     */
+    private String wxAppId;
+    /**
+     * 微信服务号ID
+     */
+    private String wxServiceAppId;
+    /**
+     * 商户号
+     */
+    private String wxMchId;
+    /**
+     * 微信key
+     */
+    private String wxPayKey;
+    /**
+     * 支付回调地址
+     */
+    private String wxNotifyUrl;
+    /**
+     * 支付回显地址
+     */
+    private String wxReturnUrl;
+    /**
+     * 微信secret
+     */
+    private String wxAppSecret;
+    /**
+     * 微信公众号secret
+     */
+    private String wxPublicSecretKey;
+    /**
+     * 微信证书位置
+     */
+    private String wxCertPath;
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/RestProperties.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/RestProperties.java
new file mode 100644
index 0000000..0d74a95
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/properties/RestProperties.java
@@ -0,0 +1,57 @@
+package com.ruoyi.order.util.properties;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 项目相关配置
+ *
+ * @author fengshuonan
+ * @date 2017年10月23日16:44:15
+ */
+@Configuration
+@ConfigurationProperties(prefix = RestProperties.REST_PREFIX)
+public class RestProperties {
+
+    public static final String REST_PREFIX = "rest";
+
+    private boolean authOpen = true;
+
+    private boolean signOpen = true;
+
+    private boolean swaggerOpen = true;
+
+    private String fileUploadPath;
+
+    public boolean isAuthOpen() {
+        return authOpen;
+    }
+
+    public void setAuthOpen(boolean authOpen) {
+        this.authOpen = authOpen;
+    }
+
+    public boolean isSignOpen() {
+        return signOpen;
+    }
+
+    public void setSignOpen(boolean signOpen) {
+        this.signOpen = signOpen;
+    }
+
+    public boolean isSwaggerOpen() {
+        return swaggerOpen;
+    }
+
+    public void setSwaggerOpen(boolean swaggerOpen) {
+        this.swaggerOpen = swaggerOpen;
+    }
+
+    public String getFileUploadPath() {
+        return fileUploadPath;
+    }
+
+    public void setFileUploadPath(String fileUploadPath) {
+        this.fileUploadPath = fileUploadPath;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/BasicType.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/BasicType.java
new file mode 100644
index 0000000..4c07e1f
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/BasicType.java
@@ -0,0 +1,38 @@
+package com.ruoyi.order.util.support;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 基本变量类型的枚举
+ *
+ * @author xiaoleilu
+ */
+public enum BasicType {
+    BYTE, SHORT, INT, INTEGER, LONG, DOUBLE, FLOAT, BOOLEAN, CHAR, CHARACTER, STRING;
+
+    /**
+     * 原始类型为Key,包装类型为Value,例如: int.class -> Integer.class.
+     */
+    public static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>(8);
+
+    /**
+     * 包装类型为Key,原始类型为Value,例如: Integer.class -> int.class.
+     */
+    public static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>(8);
+
+    static {
+        wrapperPrimitiveMap.put(Boolean.class, boolean.class);
+        wrapperPrimitiveMap.put(Byte.class, byte.class);
+        wrapperPrimitiveMap.put(Character.class, char.class);
+        wrapperPrimitiveMap.put(Double.class, double.class);
+        wrapperPrimitiveMap.put(Float.class, float.class);
+        wrapperPrimitiveMap.put(Integer.class, int.class);
+        wrapperPrimitiveMap.put(Long.class, long.class);
+        wrapperPrimitiveMap.put(Short.class, short.class);
+
+        for (Map.Entry<Class<?>, Class<?>> entry : wrapperPrimitiveMap.entrySet()) {
+            primitiveWrapperMap.put(entry.getValue(), entry.getKey());
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/CollectionKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/CollectionKit.java
new file mode 100644
index 0000000..9238e7e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/CollectionKit.java
@@ -0,0 +1,833 @@
+package com.ruoyi.order.util.support;
+
+
+
+import com.ruoyi.common.core.exception.ServiceException;
+
+import java.lang.reflect.Array;
+import java.util.*;
+import java.util.Map.Entry;
+
+/**
+ * 集合相关工具类,包括数组
+ *
+ * @author xiaoleilu
+ */
+public class CollectionKit {
+
+    private CollectionKit() {
+        // 静态类不可实例化
+    }
+
+    /**
+     * 以 conjunction 为分隔符将集合转换为字符串
+     *
+     * @param <T>         被处理的集合
+     * @param collection  集合
+     * @param conjunction 分隔符
+     * @return 连接后的字符串
+     */
+    public static <T> String join(Iterable<T> collection, String conjunction) {
+        StringBuilder sb = new StringBuilder();
+        boolean isFirst = true;
+        for (T item : collection) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                sb.append(conjunction);
+            }
+            sb.append(item);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 以 conjunction 为分隔符将数组转换为字符串
+     *
+     * @param <T>         被处理的集合
+     * @param array       数组
+     * @param conjunction 分隔符
+     * @return 连接后的字符串
+     */
+    public static <T> String join(T[] array, String conjunction) {
+        StringBuilder sb = new StringBuilder();
+        boolean isFirst = true;
+        for (T item : array) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                sb.append(conjunction);
+            }
+            sb.append(item);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将多个集合排序并显示不同的段落(分页)
+     *
+     * @param pageNo     页码
+     * @param numPerPage 每页的条目数
+     * @param comparator 比较器
+     * @param colls      集合数组
+     * @return 分页后的段落内容
+     */
+    @SafeVarargs
+    public static <T> List<T> sortPageAll(int pageNo, int numPerPage, Comparator<T> comparator, Collection<T>... colls) {
+        final List<T> result = new ArrayList<T>();
+        for (Collection<T> coll : colls) {
+            result.addAll(coll);
+        }
+
+        Collections.sort(result, comparator);
+
+        //第一页且数目少于第一页显示的数目
+        if (pageNo <= 1 && result.size() <= numPerPage) {
+            return result;
+        }
+
+        final int[] startEnd = PageKit.transToStartEnd(pageNo, numPerPage);
+        return result.subList(startEnd[0], startEnd[1]);
+    }
+
+    /**
+     * 将多个集合排序并显示不同的段落(分页)
+     * @param pageNo 页码
+     * @param numPerPage 每页的条目数
+     * @param comparator 比较器
+     * @param colls 集合数组
+     * @return 分业后的段落内容
+     */
+//	@SafeVarargs
+//	public static <T> List<T> sortPageAll2(int pageNo, int numPerPage, Comparator<T> comparator, Collection<T>... colls) {
+//		BoundedPriorityQueue<T> queue = new BoundedPriorityQueue<T>(pageNo * numPerPage);
+//		for (Collection<T> coll : colls) {
+//			queue.addAll(coll);
+//		}
+//
+//		//第一页且数目少于第一页显示的数目
+//		if(pageNo <=1 && queue.size() <= numPerPage) {
+//			return queue.toList();
+//		}
+//
+//		final int[] startEnd = PageKit.transToStartEnd(pageNo, numPerPage);
+//		return queue.toList().subList(startEnd[0], startEnd[1]);
+//	}
+
+    /**
+     * 将Set排序(根据Entry的值)
+     *
+     * @param set 被排序的Set
+     * @return 排序后的Set
+     */
+    public static List<Entry<Long, Long>> sortEntrySetToList(Set<Entry<Long, Long>> set) {
+        List<Entry<Long, Long>> list = new LinkedList<Entry<Long, Long>>(set);
+        Collections.sort(list, new Comparator<Entry<Long, Long>>() {
+
+            @Override
+            public int compare(Entry<Long, Long> o1, Entry<Long, Long> o2) {
+                if (o1.getValue() > o2.getValue()) {
+                    return 1;
+                }
+                if (o1.getValue() < o2.getValue()) {
+                    return -1;
+                }
+                return 0;
+            }
+        });
+        return list;
+    }
+
+    /**
+     * 切取部分数据
+     *
+     * @param <T>             集合元素类型
+     * @param surplusAlaDatas 原数据
+     * @param partSize        每部分数据的长度
+     * @return 切取出的数据或null
+     */
+    public static <T> List<T> popPart(Stack<T> surplusAlaDatas, int partSize) {
+        if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0) {
+            return null;
+        }
+
+        final List<T> currentAlaDatas = new ArrayList<T>();
+        int size = surplusAlaDatas.size();
+        // 切割
+        if (size > partSize) {
+            for (int i = 0; i < partSize; i++) {
+                currentAlaDatas.add(surplusAlaDatas.pop());
+            }
+        } else {
+            for (int i = 0; i < size; i++) {
+                currentAlaDatas.add(surplusAlaDatas.pop());
+            }
+        }
+        return currentAlaDatas;
+    }
+
+    /**
+     * 切取部分数据
+     *
+     * @param <T>             集合元素类型
+     * @param surplusAlaDatas 原数据
+     * @param partSize        每部分数据的长度
+     * @return 切取出的数据或null
+     */
+    public static <T> List<T> popPart(Deque<T> surplusAlaDatas, int partSize) {
+        if (surplusAlaDatas == null || surplusAlaDatas.size() <= 0) {
+            return null;
+        }
+
+        final List<T> currentAlaDatas = new ArrayList<T>();
+        int size = surplusAlaDatas.size();
+        // 切割
+        if (size > partSize) {
+            for (int i = 0; i < partSize; i++) {
+                currentAlaDatas.add(surplusAlaDatas.pop());
+            }
+        } else {
+            for (int i = 0; i < size; i++) {
+                currentAlaDatas.add(surplusAlaDatas.pop());
+            }
+        }
+        return currentAlaDatas;
+    }
+
+    /**
+     * 新建一个HashMap
+     *
+     * @return HashMap对象
+     */
+    public static <T, K> HashMap<T, K> newHashMap() {
+        return new HashMap<T, K>();
+    }
+
+    /**
+     * 新建一个HashMap
+     *
+     * @param size 初始大小,由于默认负载因子0.75,传入的size会实际初始大小为size / 0.75
+     * @return HashMap对象
+     */
+    public static <T, K> HashMap<T, K> newHashMap(int size) {
+        return new HashMap<T, K>((int) (size / 0.75));
+    }
+
+    /**
+     * 新建一个HashSet
+     *
+     * @return HashSet对象
+     */
+    public static <T> HashSet<T> newHashSet() {
+        return new HashSet<T>();
+    }
+
+    /**
+     * 新建一个HashSet
+     *
+     * @return HashSet对象
+     */
+    @SafeVarargs
+    public static <T> HashSet<T> newHashSet(T... ts) {
+        HashSet<T> set = new HashSet<T>();
+        for (T t : ts) {
+            set.add(t);
+        }
+        return set;
+    }
+
+    /**
+     * 新建一个ArrayList
+     *
+     * @return ArrayList对象
+     */
+    public static <T> ArrayList<T> newArrayList() {
+        return new ArrayList<T>();
+    }
+
+    /**
+     * 新建一个ArrayList
+     *
+     * @return ArrayList对象
+     */
+    @SafeVarargs
+    public static <T> ArrayList<T> newArrayList(T... values) {
+        return new ArrayList<T>(Arrays.asList(values));
+    }
+
+    /**
+     * 将新元素添加到已有数组中<br/>
+     * 添加新元素会生成一个新的数组,不影响原数组
+     *
+     * @param buffer     已有数组
+     * @param newElement 新元素
+     * @return 新数组
+     */
+    public static <T> T[] append(T[] buffer, T newElement) {
+        T[] t = resize(buffer, buffer.length + 1, newElement.getClass());
+        t[buffer.length] = newElement;
+        return t;
+    }
+
+    /**
+     * 生成一个新的重新设置大小的数组
+     *
+     * @param buffer        原数组
+     * @param newSize       新的数组大小
+     * @param componentType 数组元素类型
+     * @return 调整后的新数组
+     */
+    public static <T> T[] resize(T[] buffer, int newSize, Class<?> componentType) {
+        T[] newArray = newArray(componentType, newSize);
+        System.arraycopy(buffer, 0, newArray, 0, buffer.length >= newSize ? newSize : buffer.length);
+        return newArray;
+    }
+
+    /**
+     * 新建一个空数组
+     *
+     * @param componentType 元素类型
+     * @param newSize       大小
+     * @return 空数组
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T[] newArray(Class<?> componentType, int newSize) {
+        return (T[]) Array.newInstance(componentType, newSize);
+    }
+
+    /**
+     * 生成一个新的重新设置大小的数组<br/>
+     * 新数组的类型为原数组的类型
+     *
+     * @param buffer  原数组
+     * @param newSize 新的数组大小
+     * @return 调整后的新数组
+     */
+    public static <T> T[] resize(T[] buffer, int newSize) {
+        return resize(buffer, newSize, buffer.getClass().getComponentType());
+    }
+
+    /**
+     * 将多个数组合并在一起<br>
+     * 忽略null的数组
+     *
+     * @param arrays 数组集合
+     * @return 合并后的数组
+     */
+    @SafeVarargs
+    public static <T> T[] addAll(T[]... arrays) {
+        if (arrays.length == 1) {
+            return arrays[0];
+        }
+
+        int length = 0;
+        for (T[] array : arrays) {
+            if (array == null) {
+                continue;
+            }
+            length += array.length;
+        }
+        T[] result = newArray(arrays.getClass().getComponentType().getComponentType(), length);
+
+        length = 0;
+        for (T[] array : arrays) {
+            if (array == null) {
+                continue;
+            }
+            System.arraycopy(array, 0, result, length, array.length);
+            length += array.length;
+        }
+        return result;
+    }
+
+    /**
+     * 克隆数组
+     *
+     * @param array 被克隆的数组
+     * @return 新数组
+     */
+    public static <T> T[] clone(T[] array) {
+        if (array == null) {
+            return null;
+        }
+        return array.clone();
+    }
+
+    /**
+     * 生成一个数字列表<br>
+     * 自动判定正序反序
+     *
+     * @param excludedEnd 结束的数字(不包含)
+     * @return 数字列表
+     */
+    public static int[] range(int excludedEnd) {
+        return range(0, excludedEnd, 1);
+    }
+
+    /**
+     * 生成一个数字列表<br>
+     * 自动判定正序反序
+     *
+     * @param includedStart 开始的数字(包含)
+     * @param excludedEnd   结束的数字(不包含)
+     * @return 数字列表
+     */
+    public static int[] range(int includedStart, int excludedEnd) {
+        return range(includedStart, excludedEnd, 1);
+    }
+
+    /**
+     * 生成一个数字列表<br>
+     * 自动判定正序反序
+     *
+     * @param includedStart 开始的数字(包含)
+     * @param excludedEnd   结束的数字(不包含)
+     * @param step          步进
+     * @return 数字列表
+     */
+    public static int[] range(int includedStart, int excludedEnd, int step) {
+        if (includedStart > excludedEnd) {
+            int tmp = includedStart;
+            includedStart = excludedEnd;
+            excludedEnd = tmp;
+        }
+
+        if (step <= 0) {
+            step = 1;
+        }
+
+        int deviation = excludedEnd - includedStart;
+        int length = deviation / step;
+        if (deviation % step != 0) {
+            length += 1;
+        }
+        int[] range = new int[length];
+        for (int i = 0; i < length; i++) {
+            range[i] = includedStart;
+            includedStart += step;
+        }
+        return range;
+    }
+
+    /**
+     * 截取数组的部分
+     *
+     * @param list  被截取的数组
+     * @param start 开始位置(包含)
+     * @param end   结束位置(不包含)
+     * @return 截取后的数组,当开始位置超过最大时,返回null
+     */
+    public static <T> List<T> sub(List<T> list, int start, int end) {
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+
+        if (start < 0) {
+            start = 0;
+        }
+        if (end < 0) {
+            end = 0;
+        }
+
+        if (start > end) {
+            int tmp = start;
+            start = end;
+            end = tmp;
+        }
+
+        final int size = list.size();
+        if (end > size) {
+            if (start >= size) {
+                return null;
+            }
+            end = size;
+        }
+
+        return list.subList(start, end);
+    }
+
+    /**
+     * 截取集合的部分
+     *
+     * @param list  被截取的数组
+     * @param start 开始位置(包含)
+     * @param end   结束位置(不包含)
+     * @return 截取后的数组,当开始位置超过最大时,返回null
+     */
+    public static <T> List<T> sub(Collection<T> list, int start, int end) {
+        if (list == null || list.isEmpty()) {
+            return null;
+        }
+
+        return sub(new ArrayList<T>(list), start, end);
+    }
+
+    /**
+     * 数组是否为空
+     *
+     * @param array 数组
+     * @return 是否为空
+     */
+    public static <T> boolean isEmpty(T[] array) {
+        return array == null || array.length == 0;
+    }
+
+    /**
+     * 数组是否为非空
+     *
+     * @param array 数组
+     * @return 是否为非空
+     */
+    public static <T> boolean isNotEmpty(T[] array) {
+        return false == isEmpty(array);
+    }
+
+    /**
+     * 集合是否为空
+     *
+     * @param collection 集合
+     * @return 是否为空
+     */
+    public static boolean isEmpty(Collection<?> collection) {
+        return collection == null || collection.isEmpty();
+    }
+
+    /**
+     * 集合是否为非空
+     *
+     * @param collection 集合
+     * @return 是否为非空
+     */
+    public static boolean isNotEmpty(Collection<?> collection) {
+        return false == isEmpty(collection);
+    }
+
+    /**
+     * Map是否为空
+     *
+     * @param map 集合
+     * @return 是否为空
+     */
+    public static boolean isEmpty(Map<?, ?> map) {
+        return map == null || map.isEmpty();
+    }
+
+    /**
+     * Map是否为非空
+     *
+     * @param map 集合
+     * @return 是否为非空
+     */
+    public static <T> boolean isNotEmpty(Map<?, ?> map) {
+        return false == isEmpty(map);
+    }
+
+    /**
+     * 映射键值(参考Python的zip()函数)<br>
+     * 例如:<br>
+     * keys =    [a,b,c,d]<br>
+     * values = [1,2,3,4]<br>
+     * 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
+     * 如果两个数组长度不同,则只对应最短部分
+     *
+     * @param keys   键列表
+     * @param values 值列表
+     * @return Map
+     */
+    public static <T, K> Map<T, K> zip(T[] keys, K[] values) {
+        if (isEmpty(keys) || isEmpty(values)) {
+            return null;
+        }
+
+        final int size = Math.min(keys.length, values.length);
+        final Map<T, K> map = new HashMap<T, K>((int) (size / 0.75));
+        for (int i = 0; i < size; i++) {
+            map.put(keys[i], values[i]);
+        }
+
+        return map;
+    }
+
+    /**
+     * 映射键值(参考Python的zip()函数)<br>
+     * 例如:<br>
+     * keys =    a,b,c,d<br>
+     * values = 1,2,3,4<br>
+     * delimiter = ,
+     * 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
+     * 如果两个数组长度不同,则只对应最短部分
+     *
+     * @param keys   键列表
+     * @param values 值列表
+     * @return Map
+     */
+    public static Map<String, String> zip(String keys, String values, String delimiter) {
+        return zip(StrKit.split(keys, delimiter), StrKit.split(values, delimiter));
+    }
+
+    /**
+     * 映射键值(参考Python的zip()函数)<br>
+     * 例如:<br>
+     * keys =    [a,b,c,d]<br>
+     * values = [1,2,3,4]<br>
+     * 则得到的Map是 {a=1, b=2, c=3, d=4}<br>
+     * 如果两个数组长度不同,则只对应最短部分
+     *
+     * @param keys   键列表
+     * @param values 值列表
+     * @return Map
+     */
+    public static <T, K> Map<T, K> zip(Collection<T> keys, Collection<K> values) {
+        if (isEmpty(keys) || isEmpty(values)) {
+            return null;
+        }
+
+        final List<T> keyList = new ArrayList<T>(keys);
+        final List<K> valueList = new ArrayList<K>(values);
+
+        final int size = Math.min(keys.size(), values.size());
+        final Map<T, K> map = new HashMap<T, K>((int) (size / 0.75));
+        for (int i = 0; i < size; i++) {
+            map.put(keyList.get(i), valueList.get(i));
+        }
+
+        return map;
+    }
+
+    /**
+     * 数组中是否包含元素
+     *
+     * @param array 数组
+     * @param value 被检查的元素
+     * @return 是否包含
+     */
+    public static <T> boolean contains(T[] array, T value) {
+        final Class<?> componetType = array.getClass().getComponentType();
+        boolean isPrimitive = false;
+        if (null != componetType) {
+            isPrimitive = componetType.isPrimitive();
+        }
+        for (T t : array) {
+            if (t == value) {
+                return true;
+            } else if (false == isPrimitive && null != value && value.equals(t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 将Entry集合转换为HashMap
+     *
+     * @param entryCollection entry集合
+     * @return Map
+     */
+    public static <T, K> HashMap<T, K> toMap(Collection<Entry<T, K>> entryCollection) {
+        HashMap<T, K> map = new HashMap<T, K>();
+        for (Entry<T, K> entry : entryCollection) {
+            map.put(entry.getKey(), entry.getValue());
+        }
+        return map;
+    }
+
+    /**
+     * 将集合转换为排序后的TreeSet
+     *
+     * @param collection 集合
+     * @param comparator 比较器
+     * @return treeSet
+     */
+    public static <T> TreeSet<T> toTreeSet(Collection<T> collection, Comparator<T> comparator) {
+        final TreeSet<T> treeSet = new TreeSet<T>(comparator);
+        for (T t : collection) {
+            treeSet.add(t);
+        }
+        return treeSet;
+    }
+
+    /**
+     * 排序集合
+     *
+     * @param collection 集合
+     * @param comparator 比较器
+     * @return treeSet
+     */
+    public static <T> List<T> sort(Collection<T> collection, Comparator<T> comparator) {
+        List<T> list = new ArrayList<T>(collection);
+        Collections.sort(list, comparator);
+        return list;
+    }
+
+    //------------------------------------------------------------------- 基本类型的数组转换为包装类型数组
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Integer[] wrap(int... values) {
+        final int length = values.length;
+        Integer[] array = new Integer[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Long[] wrap(long... values) {
+        final int length = values.length;
+        Long[] array = new Long[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Character[] wrap(char... values) {
+        final int length = values.length;
+        Character[] array = new Character[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Byte[] wrap(byte... values) {
+        final int length = values.length;
+        Byte[] array = new Byte[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Short[] wrap(short... values) {
+        final int length = values.length;
+        Short[] array = new Short[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Float[] wrap(float... values) {
+        final int length = values.length;
+        Float[] array = new Float[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Double[] wrap(double... values) {
+        final int length = values.length;
+        Double[] array = new Double[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 将基本类型数组包装为包装类型
+     *
+     * @param values 基本类型数组
+     * @return 包装类型数组
+     */
+    public static Boolean[] wrap(boolean... values) {
+        final int length = values.length;
+        Boolean[] array = new Boolean[length];
+        for (int i = 0; i < length; i++) {
+            array[i] = values[i];
+        }
+        return array;
+    }
+
+    /**
+     * 判定给定对象是否为数组类型
+     *
+     * @param obj 对象
+     * @return 是否为数组类型
+     */
+    public static boolean isArray(Object obj) {
+        return obj.getClass().isArray();
+    }
+
+    /**
+     * 数组或集合转String
+     *
+     * @param obj 集合或数组对象
+     * @return 数组字符串,与集合转字符串格式相同
+     */
+    public static String toString(Object obj) {
+        if (null == obj) {
+            return null;
+        }
+        if (isArray(obj)) {
+            try {
+                return Arrays.deepToString((Object[]) obj);
+            } catch (Exception e) {
+                final String className = obj.getClass().getComponentType().getName();
+                switch (className) {
+                    case "long":
+                        return Arrays.toString((long[]) obj);
+                    case "int":
+                        return Arrays.toString((int[]) obj);
+                    case "short":
+                        return Arrays.toString((short[]) obj);
+                    case "char":
+                        return Arrays.toString((char[]) obj);
+                    case "byte":
+                        return Arrays.toString((byte[]) obj);
+                    case "boolean":
+                        return Arrays.toString((boolean[]) obj);
+                    case "float":
+                        return Arrays.toString((float[]) obj);
+                    case "double":
+                        return Arrays.toString((double[]) obj);
+                    default:
+                        throw new ServiceException(e.getMessage());
+                }
+            }
+        }
+        return obj.toString();
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTime.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTime.java
new file mode 100644
index 0000000..5a569e8
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTime.java
@@ -0,0 +1,70 @@
+package com.ruoyi.order.util.support;
+
+import java.util.Date;
+
+/**
+ * 封装java.util.Date
+ *
+ * @author xiaoleilu
+ */
+public class DateTime extends Date {
+    private static final long serialVersionUID = -5395712593979185936L;
+
+    /**
+     * 转换JDK date为 DateTime
+     *
+     * @param date JDK Date
+     * @return DateTime
+     */
+    public static DateTime parse(Date date) {
+        return new DateTime(date);
+    }
+
+    /**
+     * 当前时间
+     */
+    public DateTime() {
+        super();
+    }
+
+    /**
+     * 给定日期的构造
+     *
+     * @param date 日期
+     */
+    public DateTime(Date date) {
+        this(date.getTime());
+    }
+
+    /**
+     * 给定日期毫秒数的构造
+     *
+     * @param timeMillis 日期毫秒数
+     */
+    public DateTime(long timeMillis) {
+        super(timeMillis);
+    }
+
+    @Override
+    public String toString() {
+        return DateTimeKit.formatDateTime(this);
+    }
+
+    public String toString(String format) {
+        return DateTimeKit.format(this, format);
+    }
+
+    /**
+     * @return 输出精确到毫秒的标准日期形式
+     */
+    public String toMsStr() {
+        return DateTimeKit.format(this, DateTimeKit.NORM_DATETIME_MS_PATTERN);
+    }
+
+    /**
+     * @return java.util.Date
+     */
+    public Date toDate() {
+        return new Date(this.getTime());
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTimeKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTimeKit.java
new file mode 100644
index 0000000..90faf65
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/DateTimeKit.java
@@ -0,0 +1,709 @@
+package com.ruoyi.order.util.support;
+
+import com.ruoyi.common.core.exception.ServiceException;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.Locale;
+
+/**
+ * 时间工具类
+ *
+ * @author xiaoleilu
+ */
+public class DateTimeKit {
+    /**
+     * 毫秒
+     */
+    public final static long MS = 1;
+    /**
+     * 每秒钟的毫秒数
+     */
+    public final static long SECOND_MS = MS * 1000;
+    /**
+     * 每分钟的毫秒数
+     */
+    public final static long MINUTE_MS = SECOND_MS * 60;
+    /**
+     * 每小时的毫秒数
+     */
+    public final static long HOUR_MS = MINUTE_MS * 60;
+    /**
+     * 每天的毫秒数
+     */
+    public final static long DAY_MS = HOUR_MS * 24;
+
+    /**
+     * 标准日期格式
+     */
+    public final static String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    /**
+     * 标准时间格式
+     */
+    public final static String NORM_TIME_PATTERN = "HH:mm:ss";
+    /**
+     * 标准日期时间格式,精确到分
+     */
+    public final static String NORM_DATETIME_MINUTE_PATTERN = "yyyy-MM-dd HH:mm";
+    /**
+     * 标准日期时间格式,精确到秒
+     */
+    public final static String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
+    /**
+     * 标准日期时间格式,精确到毫秒
+     */
+    public final static String NORM_DATETIME_MS_PATTERN = "yyyy-MM-dd HH:mm:ss.SSS";
+    /**
+     * HTTP头中日期时间格式
+     */
+    public final static String HTTP_DATETIME_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
+
+    /**
+     * 标准日期(不含时间)格式化器
+     */
+    // private final static SimpleDateFormat NORM_DATE_FORMAT = new SimpleDateFormat(NORM_DATE_PATTERN);
+    private static ThreadLocal<SimpleDateFormat> NORM_DATE_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+        synchronized protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat(NORM_DATE_PATTERN);
+        }
+
+        ;
+    };
+    /**
+     * 标准时间格式化器
+     */
+    // private final static SimpleDateFormat NORM_TIME_FORMAT = new SimpleDateFormat(NORM_TIME_PATTERN);
+    private static ThreadLocal<SimpleDateFormat> NORM_TIME_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+        synchronized protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat(NORM_TIME_PATTERN);
+        }
+
+        ;
+    };
+    /**
+     * 标准日期时间格式化器
+     */
+    // private final static SimpleDateFormat NORM_DATETIME_FORMAT = new SimpleDateFormat(NORM_DATETIME_PATTERN);
+    private static ThreadLocal<SimpleDateFormat> NORM_DATETIME_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+        synchronized protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat(NORM_DATETIME_PATTERN);
+        }
+
+        ;
+    };
+    /**
+     * HTTP日期时间格式化器
+     */
+    // private final static SimpleDateFormat HTTP_DATETIME_FORMAT = new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
+    private static ThreadLocal<SimpleDateFormat> HTTP_DATETIME_FORMAT = new ThreadLocal<SimpleDateFormat>() {
+        synchronized protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat(HTTP_DATETIME_PATTERN, Locale.US);
+        }
+
+        ;
+    };
+
+    /**
+     * 当前时间,格式 yyyy-MM-dd HH:mm:ss
+     *
+     * @return 当前时间的标准形式字符串
+     */
+    public static String now() {
+        return formatDateTime(new DateTime());
+    }
+
+    /**
+     * 当前时间long
+     *
+     * @param isNano 是否为高精度时间
+     * @return 时间
+     */
+    public static long current(boolean isNano) {
+        return isNano ? System.nanoTime() : System.currentTimeMillis();
+    }
+
+    /**
+     * 当前日期,格式 yyyy-MM-dd
+     *
+     * @return 当前日期的标准形式字符串
+     */
+    public static String today() {
+        return formatDate(new DateTime());
+    }
+
+    /**
+     * @return 当前月份
+     */
+    public static int thisMonth() {
+        return month(date());
+    }
+
+    /**
+     * @return 今年
+     */
+    public static int thisYear() {
+        return year(date());
+    }
+
+    /**
+     * @return 当前时间
+     */
+    public static DateTime date() {
+        return new DateTime();
+    }
+
+    /**
+     * Long类型时间转为Date
+     *
+     * @param date Long类型Date(Unix时间戳)
+     * @return 时间对象
+     */
+    public static DateTime date(long date) {
+        return new DateTime(date);
+    }
+
+    /**
+     * 转换为Calendar对象
+     *
+     * @param date 日期对象
+     * @return Calendar对象
+     */
+    public static Calendar toCalendar(Date date) {
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        return cal;
+    }
+
+    /**
+     * 获得月份,从1月开始计数
+     *
+     * @param date 日期
+     * @return 月份
+     */
+    public static int month(Date date) {
+        return toCalendar(date).get(Calendar.MONTH) + 1;
+    }
+
+    /**
+     * 获得年
+     *
+     * @param date 日期
+     * @return 年
+     */
+    public static int year(Date date) {
+        return toCalendar(date).get(Calendar.YEAR);
+    }
+
+    /**
+     * 获得季节
+     *
+     * @param date 日期
+     * @return 第几个季节
+     */
+    public static int season(Date date) {
+        return toCalendar(date).get(Calendar.MONTH) / 3 + 1;
+    }
+
+    /**
+     * 获得指定日期年份和季节<br>
+     * 格式:[20131]表示2013年第一季度
+     *
+     * @param date 日期
+     * @return Season ,类似于 20132
+     */
+    public static String yearAndSeason(Date date) {
+        return yearAndSeason(toCalendar(date));
+    }
+
+    /**
+     * 获得指定日期区间内的年份和季节<br>
+     *
+     * @param startDate 其实日期(包含)
+     * @param endDate   结束日期(包含)
+     * @return Season列表 ,元素类似于 20132
+     */
+    public static LinkedHashSet<String> yearAndSeasons(Date startDate, Date endDate) {
+        final LinkedHashSet<String> seasons = new LinkedHashSet<String>();
+        if (startDate == null || endDate == null) {
+            return seasons;
+        }
+
+        final Calendar cal = Calendar.getInstance();
+        cal.setTime(startDate);
+        while (true) {
+            // 如果开始时间超出结束时间,让结束时间为开始时间,处理完后结束循环
+            if (startDate.after(endDate)) {
+                startDate = endDate;
+            }
+
+            seasons.add(yearAndSeason(cal));
+
+            if (startDate.equals(endDate)) {
+                break;
+            }
+
+            cal.add(Calendar.MONTH, 3);
+            startDate = cal.getTime();
+        }
+
+        return seasons;
+    }
+
+    // ------------------------------------ Format start ----------------------------------------------
+
+    /**
+     * 根据特定格式格式化日期
+     *
+     * @param date   被格式化的日期
+     * @param format 格式
+     * @return 格式化后的字符串
+     */
+    public static String format(Date date, String format) {
+        return new SimpleDateFormat(format).format(date);
+    }
+
+    /**
+     * 格式 yyyy-MM-dd HH:mm:ss
+     *
+     * @param date 被格式化的日期
+     * @return 格式化后的日期
+     */
+    public static String formatDateTime(Date date) {
+        if (null == date) {
+            return null;
+        }
+        return NORM_DATETIME_FORMAT.get().format(date);
+    }
+
+    /**
+     * 格式 yyyy-MM-dd
+     *
+     * @param date 被格式化的日期
+     * @return 格式化后的字符串
+     */
+    public static String formatDate(Date date) {
+        if (null == date) {
+            return null;
+        }
+        return NORM_DATE_FORMAT.get().format(date);
+    }
+
+    /**
+     * 格式化为Http的标准日期格式
+     *
+     * @param date 被格式化的日期
+     * @return HTTP标准形式日期字符串
+     */
+    public static String formatHttpDate(Date date) {
+        if (null == date) {
+            return null;
+        }
+        return HTTP_DATETIME_FORMAT.get().format(date);
+    }
+    // ------------------------------------ Format end ----------------------------------------------
+
+    // ------------------------------------ Parse start ----------------------------------------------
+
+    /**
+     * 构建DateTime对象
+     *
+     * @param dateStr          Date字符串
+     * @param simpleDateFormat 格式化器
+     * @return DateTime对象
+     */
+    public static DateTime parse(String dateStr, SimpleDateFormat simpleDateFormat) {
+        try {
+            return new DateTime(simpleDateFormat.parse(dateStr));
+        } catch (Exception e) {
+            throw new ServiceException(StrKit.format("Parse [{}] with format [{}] error!", dateStr, simpleDateFormat.toPattern()));
+        }
+    }
+
+    /**
+     * 将特定格式的日期转换为Date对象
+     *
+     * @param dateString 特定格式的日期
+     * @param format     格式,例如yyyy-MM-dd
+     * @return 日期对象
+     */
+    public static DateTime parse(String dateString, String format) {
+        return parse(dateString, new SimpleDateFormat(format));
+    }
+
+    /**
+     * 格式yyyy-MM-dd HH:mm:ss
+     *
+     * @param dateString 标准形式的时间字符串
+     * @return 日期对象
+     */
+    public static DateTime parseDateTime(String dateString) {
+        return parse(dateString, NORM_DATETIME_FORMAT.get());
+    }
+
+    /**
+     * 格式yyyy-MM-dd
+     *
+     * @param dateString 标准形式的日期字符串
+     * @return 日期对象
+     */
+    public static DateTime parseDate(String dateString) {
+        return parse(dateString, NORM_DATE_FORMAT.get());
+    }
+
+    /**
+     * 格式HH:mm:ss
+     *
+     * @param timeString 标准形式的日期字符串
+     * @return 日期对象
+     */
+    public static DateTime parseTime(String timeString) {
+        return parse(timeString, NORM_TIME_FORMAT.get());
+    }
+
+    /**
+     * 格式:<br>
+     * 1、yyyy-MM-dd HH:mm:ss<br>
+     * 2、yyyy-MM-dd<br>
+     * 3、HH:mm:ss<br>
+     * 4、yyyy-MM-dd HH:mm 5、yyyy-MM-dd HH:mm:ss.SSS
+     *
+     * @param dateStr 日期字符串
+     * @return 日期
+     */
+    public static DateTime parse(String dateStr) {
+        if (null == dateStr) {
+            return null;
+        }
+        dateStr = dateStr.trim();
+        int length = dateStr.length();
+        try {
+            if (length == NORM_DATETIME_PATTERN.length()) {
+                return parseDateTime(dateStr);
+            } else if (length == NORM_DATE_PATTERN.length()) {
+                return parseDate(dateStr);
+            } else if (length == NORM_TIME_PATTERN.length()) {
+                return parseTime(dateStr);
+            } else if (length == NORM_DATETIME_MINUTE_PATTERN.length()) {
+                return parse(dateStr, NORM_DATETIME_MINUTE_PATTERN);
+            } else if (length >= NORM_DATETIME_MS_PATTERN.length() - 2) {
+                return parse(dateStr, NORM_DATETIME_MS_PATTERN);
+            }
+        } catch (Exception e) {
+
+        }
+
+        // 没有更多匹配的时间格式
+        throw new ServiceException(StrKit.format(" [{}] format is not fit for date pattern!", dateStr));
+    }
+    // ------------------------------------ Parse end ----------------------------------------------
+
+    // ------------------------------------ Offset start ----------------------------------------------
+
+    /**
+     * 获取某天的开始时间
+     *
+     * @param date 日期
+     * @return 某天的开始时间
+     */
+    public static DateTime getBeginTimeOfDay(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, 0);
+        calendar.set(Calendar.MINUTE, 0);
+        calendar.set(Calendar.SECOND, 0);
+        calendar.set(Calendar.MILLISECOND, 0);
+        return new DateTime(calendar.getTime());
+    }
+
+    /**
+     * 获取某天的结束时间
+     *
+     * @param date 日期
+     * @return 某天的结束时间
+     */
+    public static DateTime getEndTimeOfDay(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, 23);
+        calendar.set(Calendar.MINUTE, 59);
+        calendar.set(Calendar.SECOND, 59);
+        calendar.set(Calendar.MILLISECOND, 999);
+        return new DateTime(calendar.getTime());
+    }
+
+    /**
+     * 昨天
+     *
+     * @return 昨天
+     */
+    public static DateTime yesterday() {
+        return offsiteDay(new DateTime(), -1);
+    }
+
+    /**
+     * 上周
+     *
+     * @return 上周
+     */
+    public static DateTime lastWeek() {
+        return offsiteWeek(new DateTime(), -1);
+    }
+
+    /**
+     * 上个月
+     *
+     * @return 上个月
+     */
+    public static DateTime lastMouth() {
+        return offsiteMonth(new DateTime(), -1);
+    }
+
+    /**
+     * 偏移天
+     *
+     * @param date    日期
+     * @param offsite 偏移天数,正数向未来偏移,负数向历史偏移
+     * @return 偏移后的日期
+     */
+    public static DateTime offsiteDay(Date date, int offsite) {
+        return offsiteDate(date, Calendar.DAY_OF_YEAR, offsite);
+    }
+
+    /**
+     * 偏移周
+     *
+     * @param date    日期
+     * @param offsite 偏移周数,正数向未来偏移,负数向历史偏移
+     * @return 偏移后的日期
+     */
+    public static DateTime offsiteWeek(Date date, int offsite) {
+        return offsiteDate(date, Calendar.WEEK_OF_YEAR, offsite);
+    }
+
+    /**
+     * 偏移月
+     *
+     * @param date    日期
+     * @param offsite 偏移月数,正数向未来偏移,负数向历史偏移
+     * @return 偏移后的日期
+     */
+    public static DateTime offsiteMonth(Date date, int offsite) {
+        return offsiteDate(date, Calendar.MONTH, offsite);
+    }
+
+    /**
+     * 获取指定日期偏移指定时间后的时间
+     *
+     * @param date          基准日期
+     * @param calendarField 偏移的粒度大小(小时、天、月等)使用Calendar中的常数
+     * @param offsite       偏移量,正数为向后偏移,负数为向前偏移
+     * @return 偏移后的日期
+     */
+    public static DateTime offsiteDate(Date date, int calendarField, int offsite) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(date);
+        cal.add(calendarField, offsite);
+        return new DateTime(cal.getTime());
+    }
+    // ------------------------------------ Offset end ----------------------------------------------
+
+    /**
+     * 判断两个日期相差的时长<br/>
+     * 返回 minuend - subtrahend 的差
+     *
+     * @param subtrahend 减数日期
+     * @param minuend    被减数日期
+     * @param diffField  相差的选项:相差的天、小时
+     * @return 日期差
+     */
+    public static long diff(Date subtrahend, Date minuend, long diffField) {
+        long diff = minuend.getTime() - subtrahend.getTime();
+        return diff / diffField;
+    }
+
+    /**
+     * 计时,常用于记录某段代码的执行时间,单位:纳秒
+     *
+     * @param preTime 之前记录的时间
+     * @return 时间差,纳秒
+     */
+    public static long spendNt(long preTime) {
+        return System.nanoTime() - preTime;
+    }
+
+    /**
+     * 计时,常用于记录某段代码的执行时间,单位:毫秒
+     *
+     * @param preTime 之前记录的时间
+     * @return 时间差,毫秒
+     */
+    public static long spendMs(long preTime) {
+        return System.currentTimeMillis() - preTime;
+    }
+
+    /**
+     * 格式化成yyMMddHHmm后转换为int型
+     *
+     * @param date 日期
+     * @return int
+     */
+    public static int toIntSecond(Date date) {
+        return Integer.parseInt(format(date, "yyMMddHHmm"));
+    }
+
+    /**
+     * 计算指定指定时间区间内的周数
+     *
+     * @param start 开始时间
+     * @param end   结束时间
+     * @return 周数
+     */
+    public static int weekCount(Date start, Date end) {
+        final Calendar startCalendar = Calendar.getInstance();
+        startCalendar.setTime(start);
+        final Calendar endCalendar = Calendar.getInstance();
+        endCalendar.setTime(end);
+
+        final int startWeekofYear = startCalendar.get(Calendar.WEEK_OF_YEAR);
+        final int endWeekofYear = endCalendar.get(Calendar.WEEK_OF_YEAR);
+
+        int count = endWeekofYear - startWeekofYear + 1;
+
+        if (Calendar.SUNDAY != startCalendar.get(Calendar.DAY_OF_WEEK)) {
+            count--;
+        }
+
+        return count;
+    }
+
+    /**
+     * 计时器<br>
+     * 计算某个过程话费的时间,精确到毫秒
+     *
+     * @return Timer
+     */
+    public static Timer timer() {
+        return new Timer();
+
+    }
+
+    /**
+     * 生日转为年龄,计算法定年龄
+     *
+     * @param birthDay 生日,标准日期字符串
+     * @return 年龄
+     * @throws Exception
+     */
+    public static int ageOfNow(String birthDay) {
+        return ageOfNow(parse(birthDay));
+    }
+
+    /**
+     * 生日转为年龄,计算法定年龄
+     *
+     * @param birthDay 生日
+     * @return 年龄
+     * @throws Exception
+     */
+    public static int ageOfNow(Date birthDay) {
+        return age(birthDay, date());
+    }
+
+    /**
+     * 计算相对于dateToCompare的年龄,长用于计算指定生日在某年的年龄
+     *
+     * @param birthDay      生日
+     * @param dateToCompare 需要对比的日期
+     * @return 年龄
+     * @throws Exception
+     */
+    public static int age(Date birthDay, Date dateToCompare) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(dateToCompare);
+
+        if (cal.before(birthDay)) {
+            throw new IllegalArgumentException(StrKit.format("Birthday is after date {}!", formatDate(dateToCompare)));
+        }
+
+        int year = cal.get(Calendar.YEAR);
+        int month = cal.get(Calendar.MONTH);
+        int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
+
+        cal.setTime(birthDay);
+        int age = year - cal.get(Calendar.YEAR);
+
+        int monthBirth = cal.get(Calendar.MONTH);
+        if (month == monthBirth) {
+            int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH);
+            if (dayOfMonth < dayOfMonthBirth) {
+                //如果生日在当月,但是未达到生日当天的日期,年龄减一
+                age--;
+            }
+        } else if (month < monthBirth) {
+            //如果当前月份未达到生日的月份,年龄计算减一
+            age--;
+        }
+
+        return age;
+    }
+
+    /**
+     * 计时器<br>
+     * 计算某个过程话费的时间,精确到毫秒
+     *
+     * @author Looly
+     */
+    public static class Timer {
+        private long time;
+        private boolean isNano;
+
+        public Timer() {
+            this(false);
+        }
+
+        public Timer(boolean isNano) {
+            this.isNano = isNano;
+            start();
+        }
+
+        /**
+         * @return 开始计时并返回当前时间
+         */
+        public long start() {
+            time = current(isNano);
+            return time;
+        }
+
+        /**
+         * @return 重新计时并返回从开始到当前的持续时间
+         */
+        public long durationRestart() {
+            long now = current(isNano);
+            long d = now - time;
+            time = now;
+            return d;
+        }
+
+        /**
+         * @return 从开始到当前的持续时间
+         */
+        public long duration() {
+            return current(isNano) - time;
+        }
+    }
+
+    // ------------------------------------------------------------------------ Private method start
+
+    /**
+     * 获得指定日期年份和季节<br>
+     * 格式:[20131]表示2013年第一季度
+     *
+     * @param cal 日期
+     */
+    private static String yearAndSeason(Calendar cal) {
+        return new StringBuilder().append(cal.get(Calendar.YEAR)).append(cal.get(Calendar.MONTH) / 3 + 1).toString();
+    }
+    // ------------------------------------------------------------------------ Private method end
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HexKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HexKit.java
new file mode 100644
index 0000000..419714c
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HexKit.java
@@ -0,0 +1,259 @@
+package com.ruoyi.order.util.support;
+
+import java.nio.charset.Charset;
+
+/**
+ * 十六进制(简写为hex或下标16)在数学中是一种逢16进1的进位制,一般用数字0到9和字母A到F表示(其中:A~F即10~15)。<br>
+ * 例如十进制数57,在二进制写作111001,在16进制写作39。<br>
+ * 像java,c这样的语言为了区分十六进制和十进制数值,会在十六进制数的前面加上 0x,比如0x20是十进制的32,而不是十进制的20<br>
+ * <p>
+ * 参考:https://my.oschina.net/xinxingegeya/blog/287476
+ *
+ * @author Looly
+ */
+public class HexKit {
+
+    /**
+     * 用于建立十六进制字符的输出的小写字符数组
+     */
+    private static final char[] DIGITS_LOWER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+    /**
+     * 用于建立十六进制字符的输出的大写字符数组
+     */
+    private static final char[] DIGITS_UPPER = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+    //---------------------------------------------------------------------------------------------------- encode
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data byte[]
+     * @return 十六进制char[]
+     */
+    public static char[] encodeHex(byte[] data) {
+        return encodeHex(data, true);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param str     字符串
+     * @param charset 编码
+     * @return 十六进制char[]
+     */
+    public static char[] encodeHex(String str, Charset charset) {
+        return encodeHex(StrKit.getBytes(str, charset), true);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data        byte[]
+     * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
+     * @return 十六进制char[]
+     */
+    public static char[] encodeHex(byte[] data, boolean toLowerCase) {
+        return encodeHex(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data byte[]
+     * @return 十六进制String
+     */
+    public static String encodeHexStr(byte[] data) {
+        return encodeHexStr(data, true);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data        byte[]
+     * @param toLowerCase <code>true</code> 传换成小写格式 , <code>false</code> 传换成大写格式
+     * @return 十六进制String
+     */
+    public static String encodeHexStr(byte[] data, boolean toLowerCase) {
+        return encodeHexStr(data, toLowerCase ? DIGITS_LOWER : DIGITS_UPPER);
+    }
+
+    //---------------------------------------------------------------------------------------------------- decode
+
+    /**
+     * 将十六进制字符数组转换为字符串
+     *
+     * @param hexStr  十六进制String
+     * @param charset 编码
+     * @return 字符串
+     */
+    public static String decodeHexStr(String hexStr, Charset charset) {
+        if (StrKit.isEmpty(hexStr)) {
+            return hexStr;
+        }
+        return decodeHexStr(hexStr.toCharArray(), charset);
+    }
+
+    /**
+     * 将十六进制字符数组转换为字符串
+     *
+     * @param hexData 十六进制char[]
+     * @param charset 编码
+     * @return 字符串
+     */
+    public static String decodeHexStr(char[] hexData, Charset charset) {
+        return StrKit.str(decodeHex(hexData), charset);
+    }
+
+    /**
+     * 将十六进制字符数组转换为字节数组
+     *
+     * @param hexData 十六进制char[]
+     * @return byte[]
+     * @throws RuntimeException 如果源十六进制字符数组是一个奇怪的长度,将抛出运行时异常
+     */
+    public static byte[] decodeHex(char[] hexData) {
+
+        int len = hexData.length;
+
+        if ((len & 0x01) != 0) {
+            throw new RuntimeException("Odd number of characters.");
+        }
+
+        byte[] out = new byte[len >> 1];
+
+        // two characters form the hex value.
+        for (int i = 0, j = 0; j < len; i++) {
+            int f = toDigit(hexData[j], j) << 4;
+            j++;
+            f = f | toDigit(hexData[j], j);
+            j++;
+            out[i] = (byte) (f & 0xFF);
+        }
+
+        return out;
+    }
+
+    //---------------------------------------------------------------------------------------- Private method start
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param data     byte[]
+     * @param toDigits 用于控制输出的char[]
+     * @return 十六进制String
+     */
+    private static String encodeHexStr(byte[] data, char[] toDigits) {
+        return new String(encodeHex(data, toDigits));
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符数组
+     *
+     * @param data     byte[]
+     * @param toDigits 用于控制输出的char[]
+     * @return 十六进制char[]
+     */
+    private static char[] encodeHex(byte[] data, char[] toDigits) {
+        int l = data.length;
+        char[] out = new char[l << 1];
+        // two characters form the hex value.
+        for (int i = 0, j = 0; i < l; i++) {
+            out[j++] = toDigits[(0xF0 & data[i]) >>> 4];
+            out[j++] = toDigits[0x0F & data[i]];
+        }
+        return out;
+    }
+
+    /**
+     * 将十六进制字符转换成一个整数
+     *
+     * @param ch    十六进制char
+     * @param index 十六进制字符在字符数组中的位置
+     * @return 一个整数
+     * @throws RuntimeException 当ch不是一个合法的十六进制字符时,抛出运行时异常
+     */
+    private static int toDigit(char ch, int index) {
+        int digit = Character.digit(ch, 16);
+        if (digit == -1) {
+            throw new RuntimeException("Illegal hexadecimal character " + ch + " at index " + index);
+        }
+        return digit;
+    }
+    //---------------------------------------------------------------------------------------- Private method end
+
+
+    /**
+     * 2进制转16进制
+     *
+     * @param bString 2进制字符串
+     * @return
+     */
+    public static String binary2Hex(String bString) {
+        if (bString == null || bString.equals("") || bString.length() % 8 != 0)
+            return null;
+        StringBuffer tmp = new StringBuffer();
+        int iTmp = 0;
+        for (int i = 0; i < bString.length(); i += 4) {
+            iTmp = 0;
+            for (int j = 0; j < 4; j++) {
+                iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
+            }
+            tmp.append(Integer.toHexString(iTmp));
+        }
+        return tmp.toString();
+    }
+
+    /**
+     * 16进制转2进制
+     *
+     * @param hexString
+     * @return
+     */
+    public static String hex2Binary(String hexString) {
+        if (hexString == null || hexString.length() % 2 != 0)
+            return null;
+        String bString = "", tmp;
+        for (int i = 0; i < hexString.length(); i++) {
+            tmp = "0000" + Integer.toBinaryString(Integer.parseInt(hexString.substring(i, i + 1), 16));
+            bString += tmp.substring(tmp.length() - 4);
+        }
+        return bString;
+    }
+
+    /**
+     * 将二进制转换成16进制
+     *
+     * @param buf
+     * @return
+     */
+    public static String binary2Hex(byte buf[]) {
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < buf.length; i++) {
+            String hex = Integer.toHexString(buf[i] & 0xFF);
+            if (hex.length() == 1) {
+                hex = '0' + hex;
+            }
+            sb.append(hex.toUpperCase());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将16进制转换为二进制
+     *
+     * @param hexStr
+     * @return
+     */
+    public static byte[] hex2Byte(String hexStr) {
+        if (hexStr.length() < 1)
+            return null;
+        byte[] result = new byte[hexStr.length() / 2];
+        for (int i = 0; i < hexStr.length() / 2; i++) {
+            int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
+            int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
+            result[i] = (byte) (high * 16 + low);
+        }
+        return result;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HttpKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HttpKit.java
new file mode 100644
index 0000000..a774559
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/HttpKit.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2015-2016, Chill Zhuang 庄骞 (smallchill@163.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ruoyi.order.util.support;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class HttpKit {
+
+    public static String getIp() {
+        return HttpKit.getRequest().getRemoteHost();
+    }
+
+    /**
+     * 获取所有请求的值
+     */
+    public static Map<String, String> getRequestParameters() {
+        HashMap<String, String> values = new HashMap<>();
+        HttpServletRequest request = HttpKit.getRequest();
+        Enumeration enums = request.getParameterNames();
+        while (enums.hasMoreElements()) {
+            String paramName = (String) enums.nextElement();
+            String paramValue = request.getParameter(paramName);
+            values.put(paramName, paramValue);
+        }
+        return values;
+    }
+
+    /**
+     * 获取 HttpServletRequest
+     */
+    public static HttpServletResponse getResponse() {
+        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
+        return response;
+    }
+
+    /**
+     * 获取 包装防Xss Sql注入的 HttpServletRequest
+     *
+     * @return request
+     */
+    public static HttpServletRequest getRequest() {
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        return new WafRequestWrapper(request);
+    }
+
+    /**
+     * 向指定URL发送GET方法的请求
+     *
+     * @param url   发送请求的URL
+     * @param param 请求参数
+     * @return URL 所代表远程资源的响应结果
+     */
+    public static String sendGet(String url, Map<String, String> param) {
+        String result = "";
+        BufferedReader in = null;
+        try {
+            StringBuffer query = new StringBuffer();
+
+            for (Map.Entry<String, String> kv : param.entrySet()) {
+                query.append(URLEncoder.encode(kv.getKey(), "UTF-8") + "=");
+                query.append(URLEncoder.encode(kv.getValue(), "UTF-8") + "&");
+            }
+            if (query.lastIndexOf("&") > 0) {
+                query.deleteCharAt(query.length() - 1);
+            }
+
+            String urlNameString = url + "?" + query.toString();
+            URL realUrl = new URL(urlNameString);
+            // 打开和URL之间的连接
+            URLConnection connection = realUrl.openConnection();
+            // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 建立实际的连接
+            connection.connect();
+            // 获取所有响应头字段
+            Map<String, List<String>> map = connection.getHeaderFields();
+            // 遍历所有的响应头字段
+            for (String key : map.keySet()) {
+                System.out.println(key + "--->" + map.get(key));
+            }
+            // 定义 BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            System.out.println("发送GET请求出现异常!" + e);
+            e.printStackTrace();
+        }
+        // 使用finally块来关闭输入流
+        finally {
+            try {
+                if (in != null) {
+                    in.close();
+                }
+            } catch (Exception e2) {
+                e2.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 向指定 URL 发送POST方法的请求
+     *
+     * @param url   发送请求的 URL
+     * @param param 请求参数
+     * @return 所代表远程资源的响应结果
+     */
+    public static String sendPost(String url, Map<String, String> param) {
+        PrintWriter out = null;
+        BufferedReader in = null;
+        String result = "";
+        try {
+            String para = "";
+            for (String key : param.keySet()) {
+                para += (key + "=" + param.get(key) + "&");
+            }
+            if (para.lastIndexOf("&") > 0) {
+                para = para.substring(0, para.length() - 1);
+            }
+            String urlNameString = url + "?" + para;
+            URL realUrl = new URL(urlNameString);
+            // 打开和URL之间的连接
+            URLConnection conn = realUrl.openConnection();
+            // 设置通用的请求属性
+            conn.setRequestProperty("accept", "*/*");
+            conn.setRequestProperty("connection", "Keep-Alive");
+            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 发送POST请求必须设置如下两行
+            conn.setDoOutput(true);
+            conn.setDoInput(true);
+            // 获取URLConnection对象对应的输出流
+            out = new PrintWriter(conn.getOutputStream());
+            // 发送请求参数
+            out.print(param);
+            // flush输出流的缓冲
+            out.flush();
+            // 定义BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
+            String line;
+            while ((line = in.readLine()) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            System.out.println("发送 POST 请求出现异常!" + e);
+            e.printStackTrace();
+        }
+        // 使用finally块来关闭输出流、输入流
+        finally {
+            try {
+                if (out != null) {
+                    out.close();
+                }
+                if (in != null) {
+                    in.close();
+                }
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/ObjectKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/ObjectKit.java
new file mode 100644
index 0000000..bef23de
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/ObjectKit.java
@@ -0,0 +1,21 @@
+package com.ruoyi.order.util.support;
+
+/**
+ * 一些通用的函数
+ *
+ * @author Looly
+ */
+public class ObjectKit {
+    /**
+     * 比较两个对象是否相等。<br>
+     * 相同的条件有两个,满足其一即可:<br>
+     * 1. obj1 == null && obj2 == null; 2. obj1.equals(obj2)
+     *
+     * @param obj1 对象1
+     * @param obj2 对象2
+     * @return 是否相等
+     */
+    public static boolean equals(Object obj1, Object obj2) {
+        return (obj1 != null) ? (obj1.equals(obj2)) : (obj2 == null);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/PageKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/PageKit.java
new file mode 100644
index 0000000..74ca344
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/PageKit.java
@@ -0,0 +1,52 @@
+package com.ruoyi.order.util.support;
+
+/**
+ * 分页工具类
+ *
+ * @author xiaoleilu
+ */
+public class PageKit {
+
+    /**
+     * 将页数和每页条目数转换为开始位置和结束位置<br>
+     * 此方法用于不包括结束位置的分页方法<br>
+     * 例如:<br>
+     * 页码:1,每页10 -> [0, 10]<br>
+     * 页码:2,每页10 -> [10, 20]<br>
+     * 。。。<br>
+     *
+     * @param pageNo       页码(从1计数)
+     * @param countPerPage 每页条目数
+     * @return 第一个数为开始位置,第二个数为结束位置
+     */
+    public static int[] transToStartEnd(int pageNo, int countPerPage) {
+        if (pageNo < 1) {
+            pageNo = 1;
+        }
+
+        if (countPerPage < 1) {
+            countPerPage = 0;
+//			LogKit.warn("Count per page  [" + countPerPage + "] is not valid!");
+        }
+
+        int start = (pageNo - 1) * countPerPage;
+        int end = start + countPerPage;
+
+        return new int[]{start, end};
+    }
+
+    /**
+     * 根据总数计算总页数
+     *
+     * @param totalCount 总数
+     * @param numPerPage 每页数
+     * @return 总页数
+     */
+    public static int totalPage(int totalCount, int numPerPage) {
+        if (numPerPage == 0) {
+            return 0;
+        }
+        return totalCount % numPerPage == 0 ? (totalCount / numPerPage)
+                : (totalCount / numPerPage + 1);
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/StrKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/StrKit.java
new file mode 100644
index 0000000..2a7e95e
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/StrKit.java
@@ -0,0 +1,1374 @@
+package com.ruoyi.order.util.support;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+/**
+ * 字符串工具类
+ *
+ * @author xiaoleilu
+ */
+public class StrKit {
+
+    public static final String SPACE = " ";
+    public static final String DOT = ".";
+    public static final String SLASH = "/";
+    public static final String BACKSLASH = "\\";
+    public static final String EMPTY = "";
+    public static final String CRLF = "\r\n";
+    public static final String NEWLINE = "\n";
+    public static final String UNDERLINE = "_";
+    public static final String COMMA = ",";
+
+    public static final String HTML_NBSP = "&nbsp;";
+    public static final String HTML_AMP = "&amp";
+    public static final String HTML_QUOTE = "&quot;";
+    public static final String HTML_LT = "&lt;";
+    public static final String HTML_GT = "&gt;";
+
+    public static final String EMPTY_JSON = "{}";
+
+
+    /**
+     * 首字母变小写
+     */
+    public static String firstCharToLowerCase(String str) {
+        char firstChar = str.charAt(0);
+        if (firstChar >= 'A' && firstChar <= 'Z') {
+            char[] arr = str.toCharArray();
+            arr[0] += ('a' - 'A');
+            return new String(arr);
+        }
+        return str;
+    }
+
+    /**
+     * 首字母变大写
+     */
+    public static String firstCharToUpperCase(String str) {
+        char firstChar = str.charAt(0);
+        if (firstChar >= 'a' && firstChar <= 'z') {
+            char[] arr = str.toCharArray();
+            arr[0] -= ('a' - 'A');
+            return new String(arr);
+        }
+        return str;
+    }
+
+    // ------------------------------------------------------------------------ Blank
+
+    /**
+     * 字符串是否为空白 空白的定义如下: <br>
+     * 1、为null <br>
+     * 2、为不可见字符(如空格)<br>
+     * 3、""<br>
+     *
+     * @param str 被检测的字符串
+     * @return 是否为空
+     */
+    public static boolean isBlank(String str) {
+        int length;
+        if ((str == null) || ((length = str.length()) == 0)) {
+            return true;
+        }
+        for (int i = 0; i < length; i++) {
+            // 只要有一个非空字符即为非空字符串
+            if (false == Character.isWhitespace(str.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 字符串是否为非空白 空白的定义如下: <br>
+     * 1、不为null <br>
+     * 2、不为不可见字符(如空格)<br>
+     * 3、不为""<br>
+     *
+     * @param str 被检测的字符串
+     * @return 是否为非空
+     */
+    public static boolean notBlank(String str) {
+        return false == isBlank(str);
+    }
+
+    /**
+     * 是否包含空字符串
+     *
+     * @param strs 字符串列表
+     * @return 是否包含空字符串
+     */
+    public static boolean hasBlank(String... strs) {
+        if (CollectionKit.isEmpty(strs)) {
+            return true;
+        }
+        for (String str : strs) {
+            if (isBlank(str)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 给定所有字符串是否为空白
+     *
+     * @param strs 字符串
+     * @return 所有字符串是否为空白
+     */
+    public static boolean isAllBlank(String... strs) {
+        if (CollectionKit.isEmpty(strs)) {
+            return true;
+        }
+        for (String str : strs) {
+            if (notBlank(str)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // ------------------------------------------------------------------------ Empty
+
+    /**
+     * 字符串是否为空,空的定义如下 1、为null <br>
+     * 2、为""<br>
+     *
+     * @param str 被检测的字符串
+     * @return 是否为空
+     */
+    public static boolean isEmpty(String str) {
+        return str == null || str.length() == 0;
+    }
+
+    /**
+     * 字符串是否为非空白 空白的定义如下: <br>
+     * 1、不为null <br>
+     * 2、不为""<br>
+     *
+     * @param str 被检测的字符串
+     * @return 是否为非空
+     */
+    public static boolean isNotEmpty(String str) {
+        return false == isEmpty(str);
+    }
+
+    /**
+     * 当给定字符串为null时,转换为Empty
+     *
+     * @param str 被转换的字符串
+     * @return 转换后的字符串
+     */
+    public static String nullToEmpty(String str) {
+        return nullToDefault(str, EMPTY);
+    }
+
+    /**
+     * 如果字符串是<code>null</code>,则返回指定默认字符串,否则返回字符串本身。
+     *
+     * <pre>
+     * nullToDefault(null, &quot;default&quot;)  = &quot;default&quot;
+     * nullToDefault(&quot;&quot;, &quot;default&quot;)    = &quot;&quot;
+     * nullToDefault(&quot;  &quot;, &quot;default&quot;)  = &quot;  &quot;
+     * nullToDefault(&quot;bat&quot;, &quot;default&quot;) = &quot;bat&quot;
+     * </pre>
+     *
+     * @param str        要转换的字符串
+     * @param defaultStr 默认字符串
+     * @return 字符串本身或指定的默认字符串
+     */
+    public static String nullToDefault(String str, String defaultStr) {
+        return (str == null) ? defaultStr : str;
+    }
+
+    /**
+     * 当给定字符串为空字符串时,转换为<code>null</code>
+     *
+     * @param str 被转换的字符串
+     * @return 转换后的字符串
+     */
+    public static String emptyToNull(String str) {
+        return isEmpty(str) ? null : str;
+    }
+
+    /**
+     * 是否包含空字符串
+     *
+     * @param strs 字符串列表
+     * @return 是否包含空字符串
+     */
+    public static boolean hasEmpty(String... strs) {
+        if (CollectionKit.isEmpty(strs)) {
+            return true;
+        }
+
+        for (String str : strs) {
+            if (isEmpty(str)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 是否全部为空字符串
+     *
+     * @param strs 字符串列表
+     * @return 是否全部为空字符串
+     */
+    public static boolean isAllEmpty(String... strs) {
+        if (CollectionKit.isEmpty(strs)) {
+            return true;
+        }
+
+        for (String str : strs) {
+            if (isNotEmpty(str)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    // ------------------------------------------------------------------------ Trim
+
+    /**
+     * 除去字符串头尾部的空白,如果字符串是<code>null</code>,依然返回<code>null</code>。
+     *
+     * <p>
+     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
+     *
+     * <pre>
+     * trim(null)          = null
+     * trim(&quot;&quot;)            = &quot;&quot;
+     * trim(&quot;     &quot;)       = &quot;&quot;
+     * trim(&quot;abc&quot;)         = &quot;abc&quot;
+     * trim(&quot;    abc    &quot;) = &quot;abc&quot;
+     * </pre>
+     *
+     * </p>
+     *
+     * @param str 要处理的字符串
+     * @return 除去空白的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
+     */
+    public static String trim(String str) {
+        return (null == str) ? null : trim(str, 0);
+    }
+
+    /**
+     * 给定字符串数组全部做去首尾空格
+     *
+     * @param strs 字符串数组
+     */
+    public static void trim(String[] strs) {
+        if (null == strs) {
+            return;
+        }
+        String str;
+        for (int i = 0; i < strs.length; i++) {
+            str = strs[i];
+            if (null != str) {
+                strs[i] = str.trim();
+            }
+        }
+    }
+
+    /**
+     * 除去字符串头部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
+     *
+     * <p>
+     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
+     *
+     * <pre>
+     * trimStart(null)         = null
+     * trimStart(&quot;&quot;)           = &quot;&quot;
+     * trimStart(&quot;abc&quot;)        = &quot;abc&quot;
+     * trimStart(&quot;  abc&quot;)      = &quot;abc&quot;
+     * trimStart(&quot;abc  &quot;)      = &quot;abc  &quot;
+     * trimStart(&quot; abc &quot;)      = &quot;abc &quot;
+     * </pre>
+     *
+     * </p>
+     *
+     * @param str 要处理的字符串
+     * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
+     */
+    public static String trimStart(String str) {
+        return trim(str, -1);
+    }
+
+    /**
+     * 除去字符串尾部的空白,如果字符串是<code>null</code>,则返回<code>null</code>。
+     *
+     * <p>
+     * 注意,和<code>String.trim</code>不同,此方法使用<code>Character.isWhitespace</code> 来判定空白, 因而可以除去英文字符集之外的其它空白,如中文空格。
+     *
+     * <pre>
+     * trimEnd(null)       = null
+     * trimEnd(&quot;&quot;)         = &quot;&quot;
+     * trimEnd(&quot;abc&quot;)      = &quot;abc&quot;
+     * trimEnd(&quot;  abc&quot;)    = &quot;  abc&quot;
+     * trimEnd(&quot;abc  &quot;)    = &quot;abc&quot;
+     * trimEnd(&quot; abc &quot;)    = &quot; abc&quot;
+     * </pre>
+     *
+     * </p>
+     *
+     * @param str 要处理的字符串
+     * @return 除去空白的字符串,如果原字串为<code>null</code>或结果字符串为<code>""</code>,则返回 <code>null</code>
+     */
+    public static String trimEnd(String str) {
+        return trim(str, 1);
+    }
+
+    /**
+     * 除去字符串头尾部的空白符,如果字符串是<code>null</code>,依然返回<code>null</code>。
+     *
+     * @param str  要处理的字符串
+     * @param mode <code>-1</code>表示trimStart,<code>0</code>表示trim全部, <code>1</code>表示trimEnd
+     * @return 除去指定字符后的的字符串,如果原字串为<code>null</code>,则返回<code>null</code>
+     */
+    public static String trim(String str, int mode) {
+        if (str == null) {
+            return null;
+        }
+
+        int length = str.length();
+        int start = 0;
+        int end = length;
+
+        // 扫描字符串头部
+        if (mode <= 0) {
+            while ((start < end) && (Character.isWhitespace(str.charAt(start)))) {
+                start++;
+            }
+        }
+
+        // 扫描字符串尾部
+        if (mode >= 0) {
+            while ((start < end) && (Character.isWhitespace(str.charAt(end - 1)))) {
+                end--;
+            }
+        }
+
+        if ((start > 0) || (end < length)) {
+            return str.substring(start, end);
+        }
+
+        return str;
+    }
+
+    /**
+     * 是否以指定字符串开头
+     *
+     * @param str          被监测字符串
+     * @param prefix       开头字符串
+     * @param isIgnoreCase 是否忽略大小写
+     * @return 是否以指定字符串开头
+     */
+    public static boolean startWith(String str, String prefix, boolean isIgnoreCase) {
+        if (isIgnoreCase) {
+            return str.toLowerCase().startsWith(prefix.toLowerCase());
+        } else {
+            return str.startsWith(prefix);
+        }
+    }
+
+    /**
+     * 是否以指定字符串结尾
+     *
+     * @param str          被监测字符串
+     * @param suffix       结尾字符串
+     * @param isIgnoreCase 是否忽略大小写
+     * @return 是否以指定字符串结尾
+     */
+    public static boolean endWith(String str, String suffix, boolean isIgnoreCase) {
+        if (isIgnoreCase) {
+            return str.toLowerCase().endsWith(suffix.toLowerCase());
+        } else {
+            return str.endsWith(suffix);
+        }
+    }
+
+    /**
+     * 是否包含特定字符,忽略大小写,如果给定两个参数都为<code>null</code>,返回true
+     *
+     * @param str     被检测字符串
+     * @param testStr 被测试是否包含的字符串
+     * @return 是否包含
+     */
+    public static boolean containsIgnoreCase(String str, String testStr) {
+        if (null == str) {
+            //如果被监测字符串和
+            return null == testStr;
+        }
+        return str.toLowerCase().contains(testStr.toLowerCase());
+    }
+
+    /**
+     * 获得set或get方法对应的标准属性名<br/>
+     * 例如:setName 返回 name
+     *
+     * @param getOrSetMethodName
+     * @return 如果是set或get方法名,返回field, 否则null
+     */
+    public static String getGeneralField(String getOrSetMethodName) {
+        if (getOrSetMethodName.startsWith("get") || getOrSetMethodName.startsWith("set")) {
+            return cutPreAndLowerFirst(getOrSetMethodName, 3);
+        }
+        return null;
+    }
+
+    /**
+     * 生成set方法名<br/>
+     * 例如:name 返回 setName
+     *
+     * @param fieldName 属性名
+     * @return setXxx
+     */
+    public static String genSetter(String fieldName) {
+        return upperFirstAndAddPre(fieldName, "set");
+    }
+
+    /**
+     * 生成get方法名
+     *
+     * @param fieldName 属性名
+     * @return getXxx
+     */
+    public static String genGetter(String fieldName) {
+        return upperFirstAndAddPre(fieldName, "get");
+    }
+
+    /**
+     * 去掉首部指定长度的字符串并将剩余字符串首字母小写<br/>
+     * 例如:str=setName, preLength=3 -> return name
+     *
+     * @param str       被处理的字符串
+     * @param preLength 去掉的长度
+     * @return 处理后的字符串,不符合规范返回null
+     */
+    public static String cutPreAndLowerFirst(String str, int preLength) {
+        if (str == null) {
+            return null;
+        }
+        if (str.length() > preLength) {
+            char first = Character.toLowerCase(str.charAt(preLength));
+            if (str.length() > preLength + 1) {
+                return first + str.substring(preLength + 1);
+            }
+            return String.valueOf(first);
+        }
+        return null;
+    }
+
+    /**
+     * 原字符串首字母大写并在其首部添加指定字符串 例如:str=name, preString=get -> return getName
+     *
+     * @param str       被处理的字符串
+     * @param preString 添加的首部
+     * @return 处理后的字符串
+     */
+    public static String upperFirstAndAddPre(String str, String preString) {
+        if (str == null || preString == null) {
+            return null;
+        }
+        return preString + upperFirst(str);
+    }
+
+    /**
+     * 大写首字母<br>
+     * 例如:str = name, return Name
+     *
+     * @param str 字符串
+     * @return 字符串
+     */
+    public static String upperFirst(String str) {
+        return Character.toUpperCase(str.charAt(0)) + str.substring(1);
+    }
+
+    /**
+     * 小写首字母<br>
+     * 例如:str = Name, return name
+     *
+     * @param str 字符串
+     * @return 字符串
+     */
+    public static String lowerFirst(String str) {
+        if (isBlank(str)) {
+            return str;
+        }
+        return Character.toLowerCase(str.charAt(0)) + str.substring(1);
+    }
+
+    /**
+     * 去掉指定前缀
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @return 切掉后的字符串,若前缀不是 preffix, 返回原字符串
+     */
+    public static String removePrefix(String str, String prefix) {
+        if (isEmpty(str) || isEmpty(prefix)) {
+            return str;
+        }
+
+        if (str.startsWith(prefix)) {
+            return str.substring(prefix.length());
+        }
+        return str;
+    }
+
+    /**
+     * 忽略大小写去掉指定前缀
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @return 切掉后的字符串,若前缀不是 prefix, 返回原字符串
+     */
+    public static String removePrefixIgnoreCase(String str, String prefix) {
+        if (isEmpty(str) || isEmpty(prefix)) {
+            return str;
+        }
+
+        if (str.toLowerCase().startsWith(prefix.toLowerCase())) {
+            return str.substring(prefix.length());
+        }
+        return str;
+    }
+
+    /**
+     * 去掉指定后缀
+     *
+     * @param str    字符串
+     * @param suffix 后缀
+     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
+     */
+    public static String removeSuffix(String str, String suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return str;
+        }
+
+        if (str.endsWith(suffix)) {
+            return str.substring(0, str.length() - suffix.length());
+        }
+        return str;
+    }
+
+    /**
+     * 获得字符串对应byte数组
+     *
+     * @param str     字符串
+     * @param charset 编码,如果为<code>null</code>使用系统默认编码
+     * @return bytes
+     */
+    public static byte[] getBytes(String str, Charset charset) {
+        if (null == str) {
+            return null;
+        }
+        return null == charset ? str.getBytes() : str.getBytes(charset);
+    }
+
+    /**
+     * 忽略大小写去掉指定后缀
+     *
+     * @param str    字符串
+     * @param suffix 后缀
+     * @return 切掉后的字符串,若后缀不是 suffix, 返回原字符串
+     */
+    public static String removeSuffixIgnoreCase(String str, String suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return str;
+        }
+
+        if (str.toLowerCase().endsWith(suffix.toLowerCase())) {
+            return str.substring(0, str.length() - suffix.length());
+        }
+        return str;
+    }
+
+    /**
+     * 如果给定字符串不是以prefix开头的,在开头补充 prefix
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @return 补充后的字符串
+     */
+    public static String addPrefixIfNot(String str, String prefix) {
+        if (isEmpty(str) || isEmpty(prefix)) {
+            return str;
+        }
+        if (false == str.startsWith(prefix)) {
+            str = prefix + str;
+        }
+        return str;
+    }
+
+    /**
+     * 如果给定字符串不是以suffix结尾的,在尾部补充 suffix
+     *
+     * @param str    字符串
+     * @param suffix 后缀
+     * @return 补充后的字符串
+     */
+    public static String addSuffixIfNot(String str, String suffix) {
+        if (isEmpty(str) || isEmpty(suffix)) {
+            return str;
+        }
+        if (false == str.endsWith(suffix)) {
+            str += suffix;
+        }
+        return str;
+    }
+
+    /**
+     * 清理空白字符
+     *
+     * @param str 被清理的字符串
+     * @return 清理后的字符串
+     */
+    public static String cleanBlank(String str) {
+        if (str == null) {
+            return null;
+        }
+
+        return str.replaceAll("\\s*", EMPTY);
+    }
+
+    /**
+     * 切分字符串<br>
+     * a#b#c -> [a,b,c] <br>
+     * a##b#c -> [a,"",b,c]
+     *
+     * @param str       被切分的字符串
+     * @param separator 分隔符字符
+     * @return 切分后的集合
+     */
+    public static List<String> split(String str, char separator) {
+        return split(str, separator, 0);
+    }
+
+    /**
+     * 切分字符串
+     *
+     * @param str       被切分的字符串
+     * @param separator 分隔符字符
+     * @param limit     限制分片数
+     * @return 切分后的集合
+     */
+    public static List<String> split(String str, char separator, int limit) {
+        if (str == null) {
+            return null;
+        }
+        List<String> list = new ArrayList<String>(limit == 0 ? 16 : limit);
+        if (limit == 1) {
+            list.add(str);
+            return list;
+        }
+
+        boolean isNotEnd = true; // 未结束切分的标志
+        int strLen = str.length();
+        StringBuilder sb = new StringBuilder(strLen);
+        for (int i = 0; i < strLen; i++) {
+            char c = str.charAt(i);
+            if (isNotEnd && c == separator) {
+                list.add(sb.toString());
+                // 清空StringBuilder
+                sb.delete(0, sb.length());
+
+                // 当达到切分上限-1的量时,将所剩字符全部作为最后一个串
+                if (limit != 0 && list.size() == limit - 1) {
+                    isNotEnd = false;
+                }
+            } else {
+                sb.append(c);
+            }
+        }
+        list.add(sb.toString());// 加入尾串
+        return list;
+    }
+
+    /**
+     * 切分字符串<br>
+     * from jodd
+     *
+     * @param str       被切分的字符串
+     * @param delimiter 分隔符
+     * @return 字符串
+     */
+    public static String[] split(String str, String delimiter) {
+        if (str == null) {
+            return null;
+        }
+        if (str.trim().length() == 0) {
+            return new String[]{str};
+        }
+
+        int dellen = delimiter.length(); // del length
+        int maxparts = (str.length() / dellen) + 2; // one more for the last
+        int[] positions = new int[maxparts];
+
+        int i, j = 0;
+        int count = 0;
+        positions[0] = -dellen;
+        while ((i = str.indexOf(delimiter, j)) != -1) {
+            count++;
+            positions[count] = i;
+            j = i + dellen;
+        }
+        count++;
+        positions[count] = str.length();
+
+        String[] result = new String[count];
+
+        for (i = 0; i < count; i++) {
+            result[i] = str.substring(positions[i] + dellen, positions[i + 1]);
+        }
+        return result;
+    }
+
+    /**
+     * 改进JDK subString<br>
+     * index从0开始计算,最后一个字符为-1<br>
+     * 如果from和to位置一样,返回 "" <br>
+     * 如果from或to为负数,则按照length从后向前数位置,如果绝对值大于字符串长度,则from归到0,to归到length<br>
+     * 如果经过修正的index中from大于to,则互换from和to
+     * example: <br>
+     * abcdefgh 2 3 -> c <br>
+     * abcdefgh 2 -3 -> cde <br>
+     *
+     * @param string    String
+     * @param fromIndex 开始的index(包括)
+     * @param toIndex   结束的index(不包括)
+     * @return 字串
+     */
+    public static String sub(String string, int fromIndex, int toIndex) {
+        int len = string.length();
+        if (fromIndex < 0) {
+            fromIndex = len + fromIndex;
+            if (fromIndex < 0) {
+                fromIndex = 0;
+            }
+        } else if (fromIndex >= len) {
+            fromIndex = len - 1;
+        }
+        if (toIndex < 0) {
+            toIndex = len + toIndex;
+            if (toIndex < 0) {
+                toIndex = len;
+            }
+        } else if (toIndex > len) {
+            toIndex = len;
+        }
+        if (toIndex < fromIndex) {
+            int tmp = fromIndex;
+            fromIndex = toIndex;
+            toIndex = tmp;
+        }
+        if (fromIndex == toIndex) {
+            return EMPTY;
+        }
+        char[] strArray = string.toCharArray();
+        char[] newStrArray = Arrays.copyOfRange(strArray, fromIndex, toIndex);
+        return new String(newStrArray);
+    }
+
+    /**
+     * 切割前部分
+     *
+     * @param string  字符串
+     * @param toIndex 切割到的位置(不包括)
+     * @return 切割后的字符串
+     */
+    public static String subPre(String string, int toIndex) {
+        return sub(string, 0, toIndex);
+    }
+
+    /**
+     * 切割后部分
+     *
+     * @param string    字符串
+     * @param fromIndex 切割开始的位置(包括)
+     * @return 切割后的字符串
+     */
+    public static String subSuf(String string, int fromIndex) {
+        if (isEmpty(string)) {
+            return null;
+        }
+        return sub(string, fromIndex, string.length());
+    }
+
+    /**
+     * 给定字符串是否被字符包围
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @param suffix 后缀
+     * @return 是否包围,空串不包围
+     */
+    public static boolean isSurround(String str, String prefix, String suffix) {
+        if (StrKit.isBlank(str)) {
+            return false;
+        }
+        if (str.length() < (prefix.length() + suffix.length())) {
+            return false;
+        }
+
+        return str.startsWith(prefix) && str.endsWith(suffix);
+    }
+
+    /**
+     * 给定字符串是否被字符包围
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @param suffix 后缀
+     * @return 是否包围,空串不包围
+     */
+    public static boolean isSurround(String str, char prefix, char suffix) {
+        if (StrKit.isBlank(str)) {
+            return false;
+        }
+        if (str.length() < 2) {
+            return false;
+        }
+
+        return str.charAt(0) == prefix && str.charAt(str.length() - 1) == suffix;
+    }
+
+    /**
+     * 重复某个字符
+     *
+     * @param c     被重复的字符
+     * @param count 重复的数目
+     * @return 重复字符字符串
+     */
+    public static String repeat(char c, int count) {
+        char[] result = new char[count];
+        for (int i = 0; i < count; i++) {
+            result[i] = c;
+        }
+        return new String(result);
+    }
+
+    /**
+     * 重复某个字符串
+     *
+     * @param str   被重复的字符
+     * @param count 重复的数目
+     * @return 重复字符字符串
+     */
+    public static String repeat(String str, int count) {
+
+        // 检查
+        final int len = str.length();
+        final long longSize = (long) len * (long) count;
+        final int size = (int) longSize;
+        if (size != longSize) {
+            throw new ArrayIndexOutOfBoundsException("Required String length is too large: " + longSize);
+        }
+
+        final char[] array = new char[size];
+        str.getChars(0, len, array, 0);
+        int n;
+        for (n = len; n < size - n; n <<= 1) {// n <<= 1相当于n *2
+            System.arraycopy(array, 0, array, n, n);
+        }
+        System.arraycopy(array, 0, array, n, size - n);
+        return new String(array);
+    }
+
+    /**
+     * 比较两个字符串(大小写敏感)。
+     *
+     * <pre>
+     * equals(null, null)   = true
+     * equals(null, &quot;abc&quot;)  = false
+     * equals(&quot;abc&quot;, null)  = false
+     * equals(&quot;abc&quot;, &quot;abc&quot;) = true
+     * equals(&quot;abc&quot;, &quot;ABC&quot;) = false
+     * </pre>
+     *
+     * @param str1 要比较的字符串1
+     * @param str2 要比较的字符串2
+     * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
+     */
+    public static boolean equals(String str1, String str2) {
+        if (str1 == null) {
+            return str2 == null;
+        }
+
+        return str1.equals(str2);
+    }
+
+    /**
+     * 比较两个字符串(大小写不敏感)。
+     *
+     * <pre>
+     * equalsIgnoreCase(null, null)   = true
+     * equalsIgnoreCase(null, &quot;abc&quot;)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, null)  = false
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;abc&quot;) = true
+     * equalsIgnoreCase(&quot;abc&quot;, &quot;ABC&quot;) = true
+     * </pre>
+     *
+     * @param str1 要比较的字符串1
+     * @param str2 要比较的字符串2
+     * @return 如果两个字符串相同,或者都是<code>null</code>,则返回<code>true</code>
+     */
+    public static boolean equalsIgnoreCase(String str1, String str2) {
+        if (str1 == null) {
+            return str2 == null;
+        }
+
+        return str1.equalsIgnoreCase(str2);
+    }
+
+    /**
+     * 格式化文本, {} 表示占位符<br>
+     * 例如:format("aaa {} ccc", "bbb")   ---->    aaa bbb ccc
+     *
+     * @param template 文本模板,被替换的部分用 {} 表示
+     * @param values   参数值
+     * @return 格式化后的文本
+     */
+    public static String format(String template, Object... values) {
+        if (CollectionKit.isEmpty(values) || isBlank(template)) {
+            return template;
+        }
+
+        final StringBuilder sb = new StringBuilder();
+        final int length = template.length();
+
+        int valueIndex = 0;
+        char currentChar;
+        for (int i = 0; i < length; i++) {
+            if (valueIndex >= values.length) {
+                sb.append(sub(template, i, length));
+                break;
+            }
+
+            currentChar = template.charAt(i);
+            if (currentChar == '{') {
+                final char nextChar = template.charAt(++i);
+                if (nextChar == '}') {
+                    sb.append(values[valueIndex++]);
+                } else {
+                    sb.append('{').append(nextChar);
+                }
+            } else {
+                sb.append(currentChar);
+            }
+
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 格式化文本,使用 {varName} 占位<br>
+     * map = {a: "aValue", b: "bValue"}
+     * format("{a} and {b}", map)    ---->    aValue and bValue
+     *
+     * @param template 文本模板,被替换的部分用 {key} 表示
+     * @param map      参数值对
+     * @return 格式化后的文本
+     */
+    public static String format(String template, Map<?, ?> map) {
+        if (null == map || map.isEmpty()) {
+            return template;
+        }
+
+        for (Entry<?, ?> entry : map.entrySet()) {
+            template = template.replace("{" + entry.getKey() + "}", entry.getValue().toString());
+        }
+        return template;
+    }
+
+    /**
+     * 编码字符串
+     *
+     * @param str     字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 编码后的字节码
+     */
+    public static byte[] bytes(String str, String charset) {
+        return bytes(str, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
+    }
+
+    /**
+     * 编码字符串
+     *
+     * @param str     字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 编码后的字节码
+     */
+    public static byte[] bytes(String str, Charset charset) {
+        if (str == null) {
+            return null;
+        }
+
+        if (null == charset) {
+            return str.getBytes();
+        }
+        return str.getBytes(charset);
+    }
+
+    /**
+     * 将byte数组转为字符串
+     *
+     * @param bytes   byte数组
+     * @param charset 字符集
+     * @return 字符串
+     */
+    public static String str(byte[] bytes, String charset) {
+        return str(bytes, isBlank(charset) ? Charset.defaultCharset() : Charset.forName(charset));
+    }
+
+    /**
+     * 解码字节码
+     *
+     * @param data    字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 解码后的字符串
+     */
+    public static String str(byte[] data, Charset charset) {
+        if (data == null) {
+            return null;
+        }
+
+        if (null == charset) {
+            return new String(data);
+        }
+        return new String(data, charset);
+    }
+
+    /**
+     * 将编码的byteBuffer数据转换为字符串
+     *
+     * @param data    数据
+     * @param charset 字符集,如果为空使用当前系统字符集
+     * @return 字符串
+     */
+    public static String str(ByteBuffer data, String charset) {
+        if (data == null) {
+            return null;
+        }
+
+        return str(data, Charset.forName(charset));
+    }
+
+    /**
+     * 将编码的byteBuffer数据转换为字符串
+     *
+     * @param data    数据
+     * @param charset 字符集,如果为空使用当前系统字符集
+     * @return 字符串
+     */
+    public static String str(ByteBuffer data, Charset charset) {
+        if (null == charset) {
+            charset = Charset.defaultCharset();
+        }
+        return charset.decode(data).toString();
+    }
+
+    /**
+     * 字符串转换为byteBuffer
+     *
+     * @param str     字符串
+     * @param charset 编码
+     * @return byteBuffer
+     */
+    public static ByteBuffer byteBuffer(String str, String charset) {
+        return ByteBuffer.wrap(StrKit.bytes(str, charset));
+    }
+
+    /**
+     * 以 conjunction 为分隔符将多个对象转换为字符串
+     *
+     * @param conjunction 分隔符
+     * @param objs        数组
+     * @return 连接后的字符串
+     */
+    public static String join(String conjunction, Object... objs) {
+        StringBuilder sb = new StringBuilder();
+        boolean isFirst = true;
+        for (Object item : objs) {
+            if (isFirst) {
+                isFirst = false;
+            } else {
+                sb.append(conjunction);
+            }
+            sb.append(item);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将驼峰式命名的字符串转换为下划线方式。如果转换前的驼峰式命名的字符串为空,则返回空字符串。</br>
+     * 例如:HelloWorld->hello_world
+     *
+     * @param camelCaseStr 转换前的驼峰式命名的字符串
+     * @return 转换后下划线大写方式命名的字符串
+     */
+    public static String toUnderlineCase(String camelCaseStr) {
+        if (camelCaseStr == null) {
+            return null;
+        }
+
+        final int length = camelCaseStr.length();
+        StringBuilder sb = new StringBuilder();
+        char c;
+        boolean isPreUpperCase = false;
+        for (int i = 0; i < length; i++) {
+            c = camelCaseStr.charAt(i);
+            boolean isNextUpperCase = true;
+            if (i < (length - 1)) {
+                isNextUpperCase = Character.isUpperCase(camelCaseStr.charAt(i + 1));
+            }
+            if (Character.isUpperCase(c)) {
+                if (!isPreUpperCase || !isNextUpperCase) {
+                    if (i > 0) sb.append(UNDERLINE);
+                }
+                isPreUpperCase = true;
+            } else {
+                isPreUpperCase = false;
+            }
+            sb.append(Character.toLowerCase(c));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 将下划线方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。</br>
+     * 例如:hello_world->HelloWorld
+     *
+     * @param name 转换前的下划线大写方式命名的字符串
+     * @return 转换后的驼峰式命名的字符串
+     */
+    public static String toCamelCase(String name) {
+        if (name == null) {
+            return null;
+        }
+        if (name.contains(UNDERLINE)) {
+            name = name.toLowerCase();
+
+            StringBuilder sb = new StringBuilder(name.length());
+            boolean upperCase = false;
+            for (int i = 0; i < name.length(); i++) {
+                char c = name.charAt(i);
+
+                if (c == '_') {
+                    upperCase = true;
+                } else if (upperCase) {
+                    sb.append(Character.toUpperCase(c));
+                    upperCase = false;
+                } else {
+                    sb.append(c);
+                }
+            }
+            return sb.toString();
+        } else
+            return name;
+    }
+
+    /**
+     * 包装指定字符串
+     *
+     * @param str    被包装的字符串
+     * @param prefix 前缀
+     * @param suffix 后缀
+     * @return 包装后的字符串
+     */
+    public static String wrap(String str, String prefix, String suffix) {
+        return format("{}{}{}", prefix, str, suffix);
+    }
+
+    /**
+     * 指定字符串是否被包装
+     *
+     * @param str    字符串
+     * @param prefix 前缀
+     * @param suffix 后缀
+     * @return 是否被包装
+     */
+    public static boolean isWrap(String str, String prefix, String suffix) {
+        return str.startsWith(prefix) && str.endsWith(suffix);
+    }
+
+    /**
+     * 指定字符串是否被同一字符包装(前后都有这些字符串)
+     *
+     * @param str     字符串
+     * @param wrapper 包装字符串
+     * @return 是否被包装
+     */
+    public static boolean isWrap(String str, String wrapper) {
+        return isWrap(str, wrapper, wrapper);
+    }
+
+    /**
+     * 指定字符串是否被同一字符包装(前后都有这些字符串)
+     *
+     * @param str     字符串
+     * @param wrapper 包装字符
+     * @return 是否被包装
+     */
+    public static boolean isWrap(String str, char wrapper) {
+        return isWrap(str, wrapper, wrapper);
+    }
+
+    /**
+     * 指定字符串是否被包装
+     *
+     * @param str        字符串
+     * @param prefixChar 前缀
+     * @param suffixChar 后缀
+     * @return 是否被包装
+     */
+    public static boolean isWrap(String str, char prefixChar, char suffixChar) {
+        return str.charAt(0) == prefixChar && str.charAt(str.length() - 1) == suffixChar;
+    }
+
+    /**
+     * 补充字符串以满足最小长度 StrUtil.padPre("1", 3, '0');//"001"
+     *
+     * @param str       字符串
+     * @param minLength 最小长度
+     * @param padChar   补充的字符
+     * @return 补充后的字符串
+     */
+    public static String padPre(String str, int minLength, char padChar) {
+        if (str.length() >= minLength) {
+            return str;
+        }
+        StringBuilder sb = new StringBuilder(minLength);
+        for (int i = str.length(); i < minLength; i++) {
+            sb.append(padChar);
+        }
+        sb.append(str);
+        return sb.toString();
+    }
+
+    /**
+     * 补充字符串以满足最小长度 StrUtil.padEnd("1", 3, '0');//"100"
+     *
+     * @param str       字符串
+     * @param minLength 最小长度
+     * @param padChar   补充的字符
+     * @return 补充后的字符串
+     */
+    public static String padEnd(String str, int minLength, char padChar) {
+        if (str.length() >= minLength) {
+            return str;
+        }
+        StringBuilder sb = new StringBuilder(minLength);
+        sb.append(str);
+        for (int i = str.length(); i < minLength; i++) {
+            sb.append(padChar);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * 创建StringBuilder对象
+     *
+     * @return StringBuilder对象
+     */
+    public static StringBuilder builder() {
+        return new StringBuilder();
+    }
+
+    /**
+     * 创建StringBuilder对象
+     *
+     * @return StringBuilder对象
+     */
+    public static StringBuilder builder(int capacity) {
+        return new StringBuilder(capacity);
+    }
+
+    /**
+     * 创建StringBuilder对象
+     *
+     * @return StringBuilder对象
+     */
+    public static StringBuilder builder(String... strs) {
+        final StringBuilder sb = new StringBuilder();
+        for (String str : strs) {
+            sb.append(str);
+        }
+        return sb;
+    }
+
+    /**
+     * 获得StringReader
+     *
+     * @param str 字符串
+     * @return StringReader
+     */
+    public static StringReader getReader(String str) {
+        return new StringReader(str);
+    }
+
+    /**
+     * 获得StringWriter
+     *
+     * @return StringWriter
+     */
+    public static StringWriter getWriter() {
+        return new StringWriter();
+    }
+
+    /**
+     * 编码字符串
+     *
+     * @param str     字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 编码后的字节码
+     */
+    public static byte[] encode(String str, String charset) {
+        if (str == null) {
+            return null;
+        }
+
+        if (isBlank(charset)) {
+            return str.getBytes();
+        }
+        try {
+            return str.getBytes(charset);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(format("Charset [{}] unsupported!", charset));
+        }
+    }
+
+    /**
+     * 解码字节码
+     *
+     * @param data    字符串
+     * @param charset 字符集,如果此字段为空,则解码的结果取决于平台
+     * @return 解码后的字符串
+     */
+    public static String decode(byte[] data, String charset) {
+        if (data == null) {
+            return null;
+        }
+
+        if (isBlank(charset)) {
+            return new String(data);
+        }
+        try {
+            return new String(data, charset);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException(format("Charset [{}] unsupported!", charset));
+        }
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafKit.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafKit.java
new file mode 100644
index 0000000..7c184b1
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafKit.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2011-2014, hubin (jobob@qq.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.ruoyi.order.util.support;
+
+import java.util.regex.Pattern;
+
+/**
+ * Web防火墙工具类
+ * <p>
+ * @author hubin
+ * @Date 2014-5-8
+ */
+public class WafKit {
+
+    /**
+     * @Description 过滤XSS脚本内容
+     * @param value
+     * 				待处理内容
+     * @return
+     */
+    public static String stripXSS(String value) {
+        String rlt = null;
+
+        if (null != value) {
+            // NOTE: It's highly recommended to use the ESAPI library and uncomment the following line to
+            // avoid encoded attacks.
+            // value = ESAPI.encoder().canonicalize(value);
+
+            // Avoid null characters
+            rlt = value.replaceAll("", "");
+
+            // Avoid anything between script tags
+            Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid anything in a src='...' type of expression
+			/*scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+			scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE
+					| Pattern.MULTILINE | Pattern.DOTALL);
+			rlt = scriptPattern.matcher(rlt).replaceAll("");*/
+
+            // Remove any lonesome </script> tag
+            scriptPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Remove any lonesome <script ...> tag
+            scriptPattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE
+                    | Pattern.MULTILINE | Pattern.DOTALL);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid eval(...) expressions
+            scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE
+                    | Pattern.MULTILINE | Pattern.DOTALL);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid expression(...) expressions
+            scriptPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE
+                    | Pattern.MULTILINE | Pattern.DOTALL);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid javascript:... expressions
+            scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid vbscript:... expressions
+            scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+
+            // Avoid onload= expressions
+            scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE
+                    | Pattern.MULTILINE | Pattern.DOTALL);
+            rlt = scriptPattern.matcher(rlt).replaceAll("");
+        }
+
+        return rlt;
+    }
+
+    /**
+     * @Description 过滤SQL注入内容
+     * @param value
+     * 				待处理内容
+     * @return
+     */
+    public static String stripSqlInjection(String value) {
+        return (null == value) ? null : value.replaceAll("('.+--)|(--)|(%7C)", ""); //value.replaceAll("('.+--)|(--)|(\\|)|(%7C)", "");
+    }
+
+    /**
+     * @Description 过滤SQL/XSS注入内容
+     * @param value
+     * 				待处理内容
+     * @return
+     */
+    public static String stripSqlXSS(String value) {
+        return stripXSS(stripSqlInjection(value));
+    }
+
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafRequestWrapper.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafRequestWrapper.java
new file mode 100644
index 0000000..65c877d
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/util/support/WafRequestWrapper.java
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2011-2014, hubin (jobob@qq.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.ruoyi.order.util.support;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Request请求过滤包装
+ * <p>
+ * @author hubin
+ * @Date 2014-5-8
+ */
+public class WafRequestWrapper extends HttpServletRequestWrapper {
+
+    private boolean filterXSS = true;
+
+    private boolean filterSQL = true;
+
+
+    public WafRequestWrapper(HttpServletRequest request, boolean filterXSS, boolean filterSQL) {
+        super(request);
+        this.filterXSS = filterXSS;
+        this.filterSQL = filterSQL;
+    }
+
+
+    public WafRequestWrapper(HttpServletRequest request) {
+        this(request, true, true);
+    }
+
+
+    /**
+     * @Description 数组参数过滤
+     * @param parameter
+     * 				过滤参数
+     * @return
+     */
+    @Override
+    public String[] getParameterValues(String parameter) {
+        String[] values = super.getParameterValues(parameter);
+        if (values == null) {
+            return null;
+        }
+
+        int count = values.length;
+        String[] encodedValues = new String[count];
+        for (int i = 0; i < count; i++) {
+            encodedValues[i] = filterParamString(values[i]);
+        }
+
+        return encodedValues;
+    }
+
+    @Override
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    public Map getParameterMap() {
+        Map<String, String[]> primary = super.getParameterMap();
+        Map<String, String[]> result = new HashMap<String, String[]>(primary.size());
+        for (Map.Entry<String, String[]> entry : primary.entrySet()) {
+            result.put(entry.getKey(), filterEntryString(entry.getValue()));
+        }
+        return result;
+
+    }
+
+    protected String[] filterEntryString(String[] rawValue) {
+        for (int i = 0; i < rawValue.length; i++) {
+            rawValue[i] = filterParamString(rawValue[i]);
+        }
+        return rawValue;
+    }
+
+    /**
+     * @Description 参数过滤
+     * @param parameter
+     * 				过滤参数
+     * @return
+     */
+    @Override
+    public String getParameter(String parameter) {
+        return filterParamString(super.getParameter(parameter));
+    }
+
+
+    /**
+     * @Description 请求头过滤
+     * @param name
+     * 				过滤内容
+     * @return
+     */
+    @Override
+    public String getHeader(String name) {
+        return filterParamString(super.getHeader(name));
+    }
+
+
+    /**
+     * @Description Cookie内容过滤
+     * @return
+     */
+    @Override
+    public Cookie[] getCookies() {
+        Cookie[] existingCookies = super.getCookies();
+        if (existingCookies != null) {
+            for (int i = 0; i < existingCookies.length; ++i) {
+                Cookie cookie = existingCookies[i];
+                cookie.setValue(filterParamString(cookie.getValue()));
+            }
+        }
+        return existingCookies;
+    }
+
+    /**
+     * @Description 过滤字符串内容
+     * @param rawValue
+     * 				待处理内容
+     * @return
+     */
+    protected String filterParamString(String rawValue) {
+        if (null == rawValue) {
+            return null;
+        }
+        String tmpStr = rawValue;
+        if (this.filterXSS) {
+            tmpStr = WafKit.stripXSS(rawValue);
+        }
+        if (this.filterSQL) {
+            tmpStr = WafKit.stripSqlInjection(tmpStr);
+        }
+        return tmpStr;
+    }
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/vo/KuaiDiCode.java b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/vo/KuaiDiCode.java
new file mode 100644
index 0000000..c038167
--- /dev/null
+++ b/ruoyi-modules/ruoyi-order/src/main/java/com/ruoyi/order/vo/KuaiDiCode.java
@@ -0,0 +1,14 @@
+package com.ruoyi.order.vo;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Data
+public class KuaiDiCode {
+    private String comCode;
+    private String id;
+    private Integer noCount;
+    private String noPre;
+    private LocalDateTime startTime;
+}
diff --git a/ruoyi-modules/ruoyi-order/src/main/resources/conf/param.properties b/ruoyi-modules/ruoyi-order/src/main/resources/conf/param.properties
index 6a728d8..a9677e0 100644
--- a/ruoyi-modules/ruoyi-order/src/main/resources/conf/param.properties
+++ b/ruoyi-modules/ruoyi-order/src/main/resources/conf/param.properties
@@ -24,13 +24,13 @@
 # 微信开发平台(应用APPID)
 #以前的wx74f8aea529dc99d7
 
-appID = wx24b9abadcc524e29
+appID = wxe91f1af7638aa5dd
 
 # 微信支付分配的商户号ID(微信支付商户号)
-mchID = 1600685974
+mchID = 1678345627
 
 # 小程序的商户号
-XmchID = 1600685974
+XmchID = 1678345627
 
 # 应用对应的密钥(商户平台开发设置) 
 key = E10ADC3949BA59ABBE56E057F20F883E
@@ -40,6 +40,6 @@
 
 
 # 小程序的APPID
-XappID = wx742b6a65ca132418
+XappID =wxe91f1af7638aa5dd
 
 
diff --git a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
index b52a110..67f9864 100644
--- a/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
+++ b/ruoyi-modules/ruoyi-order/src/main/resources/mapper/order/OrderMapper.xml
@@ -6,6 +6,7 @@
     SELECT ifnull(count(1), 0) FROM t_order o
     WHERE
       o.goods_sku_id = #{id}
+      AND o.order_from=2
       AND o.order_status IN (2
         , 3
         , 4)
@@ -15,14 +16,16 @@
 
 
 
-  <select id="getSeckillMembers1" resultType="com.ruoyi.system.api.domain.dto.MemberOrderDTO">
-    SELECT ifnull(SUM(o.goods_quantity), 0) FROM t_order o LEFT
-    WHERE
+
+  <select id="getGoodsGroupPurchase" resultType="java.lang.Integer">
+    SELECT ifnull(SUM(o.goods_quantity), 0) FROM t_order o
+      WHERE
       o.goods_sku_id = #{goodsSkuId}
-      AND o.order_status IN (2
-        , 3)
-     and o.member_id =#{memberId}
+      AND o.order_from=3
+      AND o.order_status IN (2,3,4)
+      and o.member_id =#{memberId}
   </select>
+
 
   <select id="getOrderByGroupPurchaseId" resultType="com.ruoyi.system.api.domain.Order"
     parameterType="java.lang.Long">
@@ -85,7 +88,7 @@
   </select>
 
 
-  <select id="getOrderByGroupPurchaseMemberId" resultType="com.ruoyi.system.api.domain.vo.OrderVO">
+  <select id="getOrderByGroupPurchaseMemberId" resultType="com.ruoyi.system.api.domain.Order">
     SELECT
     o.*
     FROM

--
Gitblit v1.7.1