From 265cbe3cc187758cd024e91e39dfd488d8486a33 Mon Sep 17 00:00:00 2001
From: liujie <liujie>
Date: 星期六, 16 九月 2023 10:55:23 +0800
Subject: [PATCH] app 2.0

---
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/controller/NettyController.java                             |   48 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/CacheType.java                                 |   86 +
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java                         |    2 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/RecordAppoint.java                     |    2 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ClientPingMessage.java                         |   59 
 cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java                                |    7 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServerController.java                        |  399 +++++
 cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_two.html                          |    4 
 cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java                           |   42 
 cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionInfo.java                              |    3 
 cloud-server-course/src/main/java/com/dsh/course/util/TaskUtil.java                                                |   60 
 cloud-server-account/mb-cloud-account.iml                                                                          |    8 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/model/RecordAppoint.java                              |    2 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyServer0.java                              |   77 +
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServer.java                                  |   95 +
 cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java                       |  719 ++++++++--
 cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java                         |   10 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyChannelMap.java                              |  133 +
 cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java                       |    7 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/UserCouponClient.java                        |    8 
 cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java                                             |    8 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/IntroduceRewardsController.java                    |   10 
 cloud-server-auth/mb-cloud-auth.iml                                                                                |    8 
 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java                |   55 
 cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java                                 |    2 
 cloud-server-competition/src/main/java/com/dsh/competition/model/PaymentCompetitionVo.java                         |    2 
 cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/MallRequest.java                     |    2 
 cloud-server-course/src/main/java/com/dsh/course/entity/TCoursePackage.java                                        |    4 
 cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java                                   |   29 
 cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java                |  186 ++
 cloud-server-other/src/main/java/com/dsh/other/model/ReservationSite.java                                          |    6 
 cloud-server-course/src/main/java/com/dsh/course/controller/CourseController.java                                  |   38 
 cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java         |    2 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyWebSocketController.java                  |  205 ++
 cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/IntroduceRewardsClient.java                |    2 
 cloud-server-activity/mb-cloud-activity.iml                                                                        |    8 
 cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackagePaymentConfig.java                            |    2 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyMsg.java                                     |  165 ++
 cloud-server-competition/mb-cloud-competition.iml                                                                  |    8 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/account/AppUserClient.java                            |    7 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/createSSLContext.java                          |   31 
 cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java                    |  200 ++
 cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/ProductDetailsVo.java                       |    3 
 cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java                                      |    9 
 cloud-server-other/src/main/java/com/dsh/other/controller/StoreController.java                                     |    2 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java                            |    6 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/Global.java                                    |    9 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/BenefitVideoController.java                        |   18 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SinataUtil.java                                        |  405 +++++
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/WebSocketHandler.java                          |  180 ++
 cloud-server-other/src/main/java/com/dsh/other/entity/Site.java                                                    |   10 
 cloud-server-account/src/main/java/com/dsh/account/model/vo/classDetails/CourseVenue.java                          |    6 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SpringUtil.java                                        |   34 
 cloud-server-course/src/main/java/com/dsh/course/model/vo/RegisterCourseVo.java                                    |    3 
 cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java                         |   20 
 cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java                               |   13 
 cloud-server-competition/src/main/java/com/dsh/competition/entity/Competition.java                                 |    2 
 cloud-server-activity/src/main/java/com/dsh/activity/service/impl/BenefitsVideosServiceImpl.java                   |   36 
 cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/model/PaymentDeductionClassHour.java |    4 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/StringUtil.java                                        |  121 +
 cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/ProductDetailsVo.java                |    3 
 cloud-server-account/src/main/java/com/dsh/account/model/AddAppUserVo.java                                         |    4 
 cloud-server-gateway/pom.xml                                                                                       |    8 
 cloud-server-course/mb-cloud-course.iml                                                                            |   12 
 cloud-server-account/src/main/java/com/dsh/account/controller/ClassDetailsController.java                          |   64 
 cloud-server-activity/src/main/java/com/dsh/activity/service/BenefitsVideosService.java                            |    1 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/model/CourseOfStoreVo.java                            |    8 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ChildChannelHandler.java                       |   36 
 cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/Goods.java                           |    4 
 cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/PointDetailsVo.java                  |    4 
 cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageListVo.java                                    |    6 
 cloud-server-course/src/main/java/com/dsh/course/feignclient/model/PaymentDeductionClassHour.java                  |    4 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/course/CoursePaymentClient.java                     |    7 
 cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/CourseOfStoreVo.java                   |    6 
 cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageInfo.java                                      |    4 
 /dev/null                                                                                                          |    8 
 cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java                          |   29 
 cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java                           |   53 
 cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/CoursePackagePaymentClient.java      |   13 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/DiscardServerHandler.java                         |  153 ++
 cloud-server-other/src/main/java/com/dsh/other/model/QuerySiteInfoVo.java                                          |   13 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/Method.java                                       |   26 
 cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/ServerInit.java                                   |   25 
 cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java                   |   20 
 84 files changed, 3,890 insertions(+), 253 deletions(-)

diff --git a/cloud-server-account/mb-cloud-account.iml b/cloud-server-account/mb-cloud-account.iml
index 1daccae..13e8572 100644
--- a/cloud-server-account/mb-cloud-account.iml
+++ b/cloud-server-account/mb-cloud-account.iml
@@ -1,8 +1,2 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-</module>
\ No newline at end of file
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4" />
\ No newline at end of file
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
index fccd65a..3625888 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/AppUserController.java
@@ -3,9 +3,11 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.dsh.account.entity.TAppUser;
+import com.dsh.account.entity.TCourseInfoRecord;
 import com.dsh.account.model.*;
 import com.dsh.account.service.IVipPaymentService;
 import com.dsh.account.service.TAppUserService;
+import com.dsh.account.service.TCourseInfoRecordService;
 import com.dsh.account.util.PayMoneyUtil;
 import com.dsh.account.util.ResultUtil;
 import com.dsh.account.util.TokenUtil;
@@ -43,6 +45,9 @@
 
     @Autowired
     private TokenUtil tokenUtil;
+
+    @Autowired
+    private TCourseInfoRecordService courseInfoRecordService;
 
 
 
@@ -391,4 +396,12 @@
     public List<TAppUser> queryAppUserListByName(@RequestBody String name){
         return appUserService.list(new QueryWrapper<TAppUser>().eq("state", 1).like("name", name));
     }
+
+
+
+    @PostMapping("/appUser/addCourseInfoRecord")
+    public Boolean addCourseInfoRecord(@RequestBody TCourseInfoRecord tCourseInfoRecord){
+        boolean save = courseInfoRecordService.save(tCourseInfoRecord);
+        return save;
+    }
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/controller/ClassDetailsController.java b/cloud-server-account/src/main/java/com/dsh/account/controller/ClassDetailsController.java
index 210bd96..c7f2a49 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/controller/ClassDetailsController.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/controller/ClassDetailsController.java
@@ -3,6 +3,7 @@
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.dsh.account.entity.TAppGift;
 import com.dsh.account.entity.TStudent;
 import com.dsh.account.feignclient.competition.model.PurchaseRecordVo;
 import com.dsh.account.feignclient.course.model.RecordAppoint;
@@ -14,10 +15,7 @@
 import com.dsh.account.model.vo.sourceDetail.CouponStuAvailableVo;
 import com.dsh.account.model.vo.sourceDetail.CourseDetailsOfContinuationResp;
 import com.dsh.account.model.vo.sourceDetail.RecordTimeRequest;
-import com.dsh.account.service.EvaluateStudentService;
-import com.dsh.account.service.StudentHonorService;
-import com.dsh.account.service.TAppUserService;
-import com.dsh.account.service.TStudentService;
+import com.dsh.account.service.*;
 import com.dsh.account.util.*;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
@@ -25,6 +23,7 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.transaction.annotation.Propagation;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -59,6 +58,9 @@
 
     @Autowired
     private TokenUtil tokenUtil;
+
+    @Autowired
+    private TAppGiftService appGiftService;
 
 
 
@@ -106,6 +108,60 @@
 
     }
 
+    @ResponseBody
+    @PostMapping("/api/startCource/weeksOfGetHours")
+    @ApiOperation(value = "上课首页获取未分配课时-课程列表", tags = {"APP-开始上课"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+    })
+    public ResultUtil<Integer> weeksOfGetHours(){
+        try {
+            Integer appUserId = tokenUtil.getUserIdFormRedis();
+            if(null == appUserId){
+                return ResultUtil.tokenErr();
+            }
+            TAppGift one = appGiftService.getOne(new LambdaQueryWrapper<TAppGift>().eq(TAppGift::getUserId, appUserId));
+
+            return ResultUtil.success(one==null?0:one.getNum());
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
+
+    @ResponseBody
+    @PostMapping("/api/startCource/weeksOfAddHours")
+    @ApiOperation(value = "上课首页分配课时-课程列表", tags = {"APP-开始上课"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+            @ApiImplicitParam(value = "分配给课包id", name = "packetId", required = true, dataType = "string"),
+    })
+    public ResultUtil<Integer> weeksOfAddHours(Integer packetId){
+        try {
+            Integer appUserId = tokenUtil.getUserIdFormRedis();
+            if(null == appUserId){
+                return ResultUtil.tokenErr();
+            }
+            TAppGift one = appGiftService.getOne(new LambdaQueryWrapper<TAppGift>().eq(TAppGift::getUserId, appUserId));
+            Boolean b= false;
+            if(one!=null && one.getNum()>0){
+                 b =appGiftService.weeksOfAddHours(packetId,appUserId,one.getNum());
+            }
+            if(b){
+                // 送完清0
+                one.setNum(0);
+                appGiftService.updateById(one);
+                return ResultUtil.success();
+            }else {
+                return ResultUtil.runErr();
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
 
     @ResponseBody
     @PostMapping("/api/startCource/queryPhysical")
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/IntroduceRewardsClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/IntroduceRewardsClient.java
index f3b9d0d..1998736 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/IntroduceRewardsClient.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/activity/IntroduceRewardsClient.java
@@ -16,6 +16,8 @@
     @PostMapping("/base/introduce/useOfRewards")
     public List<PurchaseRecordVo> queryAppUsersofIntroduce(@RequestBody IntrduceOfUserRequest request);
 
+    @PostMapping("/base/introduce/getGiftList")
+    Integer getGiftList(@RequestBody String cityCode);
 
 
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/CoursePaymentClient.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/CoursePaymentClient.java
index 61a8c62..b8c26af 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/CoursePaymentClient.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/CoursePaymentClient.java
@@ -62,4 +62,11 @@
     @PostMapping("/base/coursePack/getCoursePackagePaymentOfCode")
     List<TCoursePackagePayment> getCoursePackagePaymentOfCode(@RequestBody String code);
 
+    @PostMapping("/base/coursePack/sendHours")
+    Boolean sendHours(String s);
+
+    @PostMapping("/base/coursePack/getClassHour")
+    Integer getClassHour(Integer courseConfigId);
+
+
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/CourseOfStoreVo.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/CourseOfStoreVo.java
index 8e1fff5..2c67928 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/CourseOfStoreVo.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/CourseOfStoreVo.java
@@ -36,4 +36,10 @@
 
     @ApiModelProperty(value = "预约状态")
     private Integer status;
+    @ApiModelProperty(value = "总学时数")
+    Integer allNum;
+    @ApiModelProperty(value = "已扣学时数")
+    Integer useNum;
+    @ApiModelProperty(value = "剩余学时数")
+    Integer lastNum;
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/RecordAppoint.java b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/RecordAppoint.java
index e4c0131..40394d3 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/RecordAppoint.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/feignclient/course/model/RecordAppoint.java
@@ -24,7 +24,7 @@
     @ApiModelProperty(value = "门店名称+地址")
     private String storeNameAddr;
 
-    @ApiModelProperty(value = "课状态(1待上课 2已开始 3已完成 4已取消)")
+    @ApiModelProperty(value = "课状态(1待上课 2已开始 3已完成 4已取消 5已请假 6旷课)")
     private Integer status;
 
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/AddAppUserVo.java b/cloud-server-account/src/main/java/com/dsh/account/model/AddAppUserVo.java
index d1cca9b..3062fb3 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/AddAppUserVo.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/AddAppUserVo.java
@@ -15,4 +15,8 @@
     private String password;
     @ApiModelProperty(value = "邀请人id", dataType = "int", required = false)
     private Integer referralUserId;
+
+    private String lon;
+    private String lat;
+
 }
\ No newline at end of file
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/classDetails/CourseVenue.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/classDetails/CourseVenue.java
index 87498f2..4c00225 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/classDetails/CourseVenue.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/classDetails/CourseVenue.java
@@ -37,6 +37,12 @@
 
         @ApiModelProperty(value = "预约状态:1=未预约,2=已预约")
         Integer status;
+        @ApiModelProperty(value = "总学时数")
+        Integer allNum;
+        @ApiModelProperty(value = "已扣学时数")
+        Integer useNum;
+        @ApiModelProperty(value = "剩余学时数")
+        Integer lastNum;
 
     }
 
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/Goods.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/Goods.java
index 7df80ad..b651466 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/Goods.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/Goods.java
@@ -5,6 +5,8 @@
 import lombok.Data;
 
 import java.math.BigDecimal;
+import java.util.List;
+
 
 @Data
 public class Goods {
@@ -35,5 +37,7 @@
 
     @ApiModelProperty(value = "已兑换数量")
     private Integer nums;
+    @ApiModelProperty(value = "门店id")
+    private List<Integer> shopIds;
 
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/MallRequest.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/MallRequest.java
index c52cbf0..e640c0b 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/MallRequest.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/MallRequest.java
@@ -18,6 +18,8 @@
 
     @ApiModelProperty(value = "商品类型: 1实物 2课包 3门票 4优惠券")
     private Integer goodsType;
+    @ApiModelProperty(value = "门店id")
+    private Integer shopId;
 
     @ApiModelProperty(value = "搜索内容")
     private String search;
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/PointDetailsVo.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/PointDetailsVo.java
index d644a90..eca7bd0 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/PointDetailsVo.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/PointDetailsVo.java
@@ -8,7 +8,7 @@
 import java.util.List;
 
 @Data
-public class PointDetailsVo {
+public class    PointDetailsVo {
 
     @ApiModelProperty(value = "记录id")
     private Integer detailsId;
@@ -58,4 +58,6 @@
     @ApiModelProperty(value = "兑换方式(1=积分,2=积分+现金)")
     private Integer exchangeType;
 
+    @ApiModelProperty(value = "1日卡 2月卡 3季卡 4年卡")
+    private  Integer cardType;
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/ProductDetailsVo.java b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/ProductDetailsVo.java
index 0c66d75..cce4217 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/ProductDetailsVo.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/model/vo/userBenefitDetail/ProductDetailsVo.java
@@ -64,4 +64,7 @@
     @ApiModelProperty(value = "商品类型 1实物 2课包 3门票 4优惠券")
     private Integer goodType;
 
+    @ApiModelProperty(value = "1日卡 2月卡 3季卡 4年卡")
+    private Integer cardType;
+
 }
diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java
index a76a64c..c6dc20e 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TAppUserServiceImpl.java
@@ -1,10 +1,12 @@
 package com.dsh.account.service.impl;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.dsh.account.entity.*;
 import com.dsh.account.enums.RechargeRecordEnum;
+import com.dsh.account.feignclient.activity.IntroduceRewardsClient;
 import com.dsh.account.feignclient.activity.MerChandiseClient;
 import com.dsh.account.feignclient.activity.MerChandiseStoreClient;
 import com.dsh.account.feignclient.activity.UserConponClient;
@@ -12,6 +14,7 @@
 import com.dsh.account.feignclient.competition.DeductionCompetitionsClient;
 import com.dsh.account.feignclient.competition.model.BillingDataRequestVo;
 import com.dsh.account.feignclient.competition.model.PaymentCompetition;
+import com.dsh.account.feignclient.competition.model.PurchaseRecordVo;
 import com.dsh.account.feignclient.course.CoursePackageClient;
 import com.dsh.account.feignclient.course.CoursePackageConfigClient;
 import com.dsh.account.feignclient.course.CoursePaymentClient;
@@ -33,6 +36,7 @@
 import com.dsh.account.model.vo.classDetails.RegisteredCourse;
 import com.dsh.account.model.vo.classDetails.classInsVo.ClassInfoVo;
 import com.dsh.account.model.vo.userBenefitDetail.*;
+import com.dsh.account.service.TAppGiftService;
 import com.dsh.account.service.TAppUserService;
 import com.dsh.account.util.*;
 import com.dsh.account.util.akeylogin.Md5Util;
@@ -134,6 +138,11 @@
     @Resource
     private SiteClient stClient;
 
+    @Autowired
+    private TAppGiftService appGiftService;
+
+    @Autowired
+    private IntroduceRewardsClient introduceRewardsClient;
     @Override
     public ClassInfoVo queryUserOfStus(Integer id) {
         TAppUser tAppUser = this.baseMapper.selectById(id);
@@ -217,6 +226,10 @@
                 couList.setTimeStr(courseOfStoreVo.getClassStartTime() + "-" + courseOfStoreVo.getClassEndTime());
                 couList.setDetail("¥" + courseOfStoreVo.getCoursePrice() + "/会员扣2学时");
                 couList.setStatus(courseOfStoreVo.getStatus());
+
+                couList.setAllNum(courseOfStoreVo.getAllNum());
+                couList.setUseNum(courseOfStoreVo.getUseNum());
+                couList.setLastNum(courseOfStoreVo.getLastNum());
                 courses.add(couList);
             }
             courseVenue.setCourses(courses);
@@ -279,6 +292,32 @@
         tAppUser.setState(1);
         tAppUser.setInsertTime(new Date());
         this.baseMapper.insert(tAppUser);
+
+
+        // 介绍有礼
+        if(addAppUserVo.getReferralUserId()!=null){
+            Map<String, String> geocode = gdMapGeocodingUtil.geocode(addAppUserVo.getLon(), addAppUserVo.getLat());
+            Integer num=0;
+            if(null != geocode){
+                String province = geocode.get("province");
+                String provinceCode = geocode.get("provinceCode");
+                String city = geocode.get("city");
+                String cityCode = geocode.get("cityCode");
+                 num =  introduceRewardsClient.getGiftList(cityCode);
+            }
+            TAppGift one = appGiftService.getOne(new LambdaQueryWrapper<TAppGift>().eq(TAppGift::getUserId, addAppUserVo.getReferralUserId()));
+            if(one!=null){
+                one.setNum(one.getNum()+num);
+                appGiftService.updateById(one);
+            }else {
+                TAppGift tAppGift = new TAppGift();
+                tAppGift.setUserId(addAppUserVo.getReferralUserId());
+                tAppGift.setNum(num);
+                appGiftService.save(tAppGift);
+            }
+
+        }
+
         return ResultUtil.success();
     }
 
@@ -691,6 +730,8 @@
                         commodity.setBelongsType(vicinityGood.getUserPopulation());
                         commodity.setGoodsType(1);
                         commodity.setNums(mcClient.getRedeemedQuantity(vicinityGood.getId()));
+                        List<Integer> integers = mcsClient.queryPointMerStoreIds(vicinityGood.getId());
+                        commodity.setShopIds(integers);
                         break;
                     case 2:
                         commodity.setGoodId(vicinityGood.getCoursePackageId());
@@ -707,6 +748,7 @@
                         commodity.setBelongsType(vicinityGood.getUserPopulation());
                         commodity.setGoodsType(2);
                         commodity.setNums(mcClient.getRedeemedQuantity(vicinityGood.getId()));
+                        commodity.setShopIds(mcsClient.queryPointMerStoreIds(vicinityGood.getId()));
                         break;
                     case 3:
                         commodity.setGoodId(vicinityGood.getId());
@@ -722,6 +764,7 @@
                         commodity.setBelongsType(vicinityGood.getUserPopulation());
                         commodity.setGoodsType(3);
                         commodity.setNums(mcClient.getRedeemedQuantity(vicinityGood.getId()));
+                        commodity.setShopIds(mcsClient.queryPointMerStoreIds(vicinityGood.getId()));
                         break;
                     default:
                         break;
@@ -749,6 +792,7 @@
                 goods.add(commodity);
             }
         }
+
         if (StringUtils.hasText(request.getSearch())){
             if (goods.size() > 0 ){
                 goods = goods.stream()
@@ -756,6 +800,15 @@
                         .collect(Collectors.toList());
             }
         }
+        // 2.0 门店筛选
+        if (request.getShopId()!=null){
+            if (goods.size() > 0 ){
+                goods = goods.stream()
+                        .filter(merchandise -> merchandise.getShopIds().contains(request.getShopId()))
+                        .collect(Collectors.toList());
+            }
+        }
+
         if (null != request.getRank()){
             switch (request.getRank()){
                 case 1:
diff --git a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java
index 71ee8ba..25ade80 100644
--- a/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java
+++ b/cloud-server-account/src/main/java/com/dsh/account/service/impl/TStudentServiceImpl.java
@@ -7,6 +7,7 @@
 import com.dsh.account.dto.TStudentDto;
 import com.dsh.account.entity.Coach;
 import com.dsh.account.entity.TAppUser;
+import com.dsh.account.entity.TCourseInfoRecord;
 import com.dsh.account.entity.TStudent;
 import com.dsh.account.feignclient.activity.IntroduceRewardsClient;
 import com.dsh.account.feignclient.activity.UserConponClient;
@@ -40,6 +41,7 @@
 import com.dsh.account.model.vo.sourceDetail.CourseDetailsOfContinuationResp;
 import com.dsh.account.model.vo.sourceDetail.RecordTimeRequest;
 import com.dsh.account.model.vo.userBenefitDetail.Goods;
+import com.dsh.account.service.TCourseInfoRecordService;
 import com.dsh.account.service.TStudentService;
 import com.dsh.account.util.*;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -113,6 +115,9 @@
 
     @Resource
     private CourseListClient culisClient;
+
+    @Autowired
+    private TCourseInfoRecordService courseInfoRecordService;
 
 
 
@@ -243,6 +248,7 @@
         getStuSourseList.setStartTime(startTime);
         getStuSourseList.setEndTime(endTime);
         getStuSourseList.setAppUserId(appUserId);
+        // 报名赛事
         List<PurchaseRecordVo> stuSourseList = dcttClient.getStuSourseList(getStuSourseList);
         purchaseRecordVoList.addAll(stuSourseList);
 
@@ -259,6 +265,7 @@
         getStuSessionList.setEndTime(endTime);
         getStuSessionList.setStuId(timeRequest.getStuId());
         getStuSessionList.setAppUserId(appUserId);
+        // 购买课包
         List<PurchaseRecordVo> purchaseRecordVos = sessionNameClient.queryCourseDetails(getStuSessionList);
         purchaseRecordVoList.addAll(purchaseRecordVos);
         List<TAppUser> tAppUsers = tauMapper.selectList(new QueryWrapper<TAppUser>()
@@ -270,9 +277,30 @@
             request.setStartTime(startTime);
             request.setEndTime(endTime);
             request.setUserIds(userIds);
+            // 介绍有礼
             List<PurchaseRecordVo> purchaseRecordVos1 = idrClient.queryAppUsersofIntroduce(request);
             purchaseRecordVoList.addAll(purchaseRecordVos1);
         }
+
+        LambdaQueryWrapper<TCourseInfoRecord> eq = new LambdaQueryWrapper<TCourseInfoRecord>().eq(TCourseInfoRecord::getUserId, appUserId);
+        if(timeRequest.getType()!=null){
+            eq.eq(TCourseInfoRecord::getType,timeRequest.getType());
+        }
+        // 2.0其他记录
+        List<TCourseInfoRecord> list = courseInfoRecordService.list(eq);
+        List<PurchaseRecordVo> list1=new ArrayList<>();
+        for (TCourseInfoRecord tCourseInfoRecord : list) {
+            PurchaseRecordVo purchaseRecordVo = new PurchaseRecordVo();
+            purchaseRecordVo.setPurchaseTime(new SimpleDateFormat("MM-dd HH:mm").format(tCourseInfoRecord.getTime()));
+            purchaseRecordVo.setPurchaseType(tCourseInfoRecord.getName());
+            if(tCourseInfoRecord.getType()==1){
+                purchaseRecordVo.setPurchaseAmount("+"+tCourseInfoRecord.getNum());
+            }else {
+                purchaseRecordVo.setPurchaseAmount("-"+tCourseInfoRecord.getNum());
+            }
+            list1.add(purchaseRecordVo);
+        }
+        purchaseRecordVoList.addAll(list1);
 
         if (purchaseRecordVoList.size() > 0 ){
             purchaseRecordVoList = purchaseRecordVoList.stream()
@@ -441,12 +469,14 @@
         packagePayment.setInsertTime(new Date());
         couPayClient.savePaymentCoursePackage(packagePayment);
 
+        Integer hour = couPayClient.getClassHour(request.getCourseConfigId());
+
         try {
             switch (request.getPayType()) {
                 case 1:
-                    return WeChatPayment(code,request.getPayAmount());
+                    return WeChatPayment(code,request.getPayAmount(),hour);
                 case 2:
-                    return AlipayPayment(code,request.getPayAmount());
+                    return AlipayPayment(code,request.getPayAmount(),hour);
                 case 3:
                     int i = PlaypaiGoldPayment(code,request);
                     switch (i){
@@ -469,7 +499,7 @@
     }
 
 
-    public ResultUtil WeChatPayment(String code,BigDecimal amount) throws Exception {
+    public ResultUtil WeChatPayment(String code,BigDecimal amount,Integer hour) throws Exception {
         ResultUtil weixinpay = payMoneyUtil.weixinpay("课包续费", "", code, amount.toString(),
                 "/base/coursePackage/wechatPaymentCallback", "APP", "");
         if(weixinpay.getCode() == 200){
@@ -508,6 +538,8 @@
                                 }
                                 if("SUCCESS".equals(s)){
                                     coursePackagePayment.setPayStatus(2);
+                                    coursePackagePayment.setTotalClassHours(hour);
+                                    coursePackagePayment.setLaveClassHours(hour);
                                     coursePackagePayment.setOrderNumber(transaction_id);
                                     couPayClient.updatePaymentCoursePackage(coursePackagePayment);
                                     break;
@@ -526,7 +558,7 @@
         return weixinpay;
     }
 
-    public ResultUtil AlipayPayment(String code,BigDecimal amount){
+    public ResultUtil AlipayPayment(String code,BigDecimal amount,Integer hour){
         ResultUtil alipay = payMoneyUtil.alipay("课包续费", "课包续费", "", code, amount.toString(),
                 "/base/coursePackage/alipayPaymentCallback");
         if(alipay.getCode() == 200){
@@ -562,6 +594,8 @@
                                 }
                                 if("TRADE_SUCCESS".equals(s)){
                                     coursePackagePayment.setPayStatus(2);
+                                    coursePackagePayment.setTotalClassHours(hour);
+                                    coursePackagePayment.setLaveClassHours(hour);
                                     coursePackagePayment.setOrderNumber(tradeNo);
                                     couPayClient.updatePaymentCoursePackage(coursePackagePayment);
                                     break;
diff --git a/cloud-server-activity/mb-cloud-activity.iml b/cloud-server-activity/mb-cloud-activity.iml
index 1daccae..13e8572 100644
--- a/cloud-server-activity/mb-cloud-activity.iml
+++ b/cloud-server-activity/mb-cloud-activity.iml
@@ -1,8 +1,2 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-</module>
\ No newline at end of file
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4" />
\ No newline at end of file
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/BenefitVideoController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/BenefitVideoController.java
index 1ad5527..78a9cad 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/BenefitVideoController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/BenefitVideoController.java
@@ -143,6 +143,24 @@
             return ResultUtil.runErr();
         }
     }
+    @ResponseBody
+    @PostMapping("/base/benefitsVideo/queryClassificationBenefitsVideosListOne")
+    @ApiOperation(value = "获取视频列表", tags = {"APP-线上课得积分", "APP-看视频得奖励"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(value = "位置(1=线上课得积分,2=看视频得奖励)", name = "position", dataType = "int", required = true),
+            @ApiImplicitParam(value = "搜索内容", name = "search", dataType = "string", required = false),
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResultUtil<List<BenefitsVideoClassificationListVo>> queryClassificationBenefitsVideosListOne(Integer position, String search){
+        try {
+            Integer uid = -1;
+            List<BenefitsVideoClassificationListVo> listVos = bfvService.queryClassificationBenefitsVideosListOne(uid, position, search);
+            return ResultUtil.success(listVos);
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
 
 
     @ResponseBody
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/IntroduceRewardsController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/IntroduceRewardsController.java
index 1c36d9b..1f2dbd0 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/IntroduceRewardsController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/IntroduceRewardsController.java
@@ -1,6 +1,7 @@
 package com.dsh.activity.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dsh.activity.entity.IntroduceRewards;
 import com.dsh.activity.feignclient.model.IntrduceOfUserRequest;
@@ -12,7 +13,9 @@
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @Api
 @CrossOrigin
@@ -45,4 +48,11 @@
         return recordVos;
     }
 
+    @PostMapping("/base/introduce/getGiftList")
+    public Integer getGiftList(@RequestBody String cityCode){
+        List<IntroduceRewards> list = idrService.list(new LambdaQueryWrapper<IntroduceRewards>().eq(IntroduceRewards::getCityCode,cityCode).ge(IntroduceRewards::getStartTime,new Date()).le(IntroduceRewards::getEndTime,new Date()));
+        int sum = list.stream().mapToInt(IntroduceRewards::getGiveClass).sum();
+        return sum;
+    }
+
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
index b9699bb..bcd90d1 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/PointMercharsController.java
@@ -148,6 +148,7 @@
         SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
         ProductDetailsVo detailsVo = new ProductDetailsVo();
         PointsMerchandise merchandise = pmdsService.getById(detailRequest.getGoodId());
+        detailsVo.setCardType(merchandise.getCardTye());
         switch (detailRequest.getGoodsType()){
             case 2:
 //                课包
@@ -370,8 +371,11 @@
         SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
         PointDetailsVo detailsVo = new PointDetailsVo();
         UserPointsMerchandise byId = upmseService.getById(speMercharsId);
+
         if (ToolUtil.isNotEmpty(byId)){
             PointsMerchandise pmdsServiceById = pmdsService.getById(byId.getPointsMerchandiseId());
+            // 2.0
+            detailsVo.setCardType(pmdsServiceById.getCardTye());
             detailsVo.setExchangeType(pmdsServiceById.getRedemptionMethod());
             detailsVo.setGoodType(pmdsServiceById.getType());
             if (pmdsServiceById.getRedemptionMethod() == 1){
@@ -434,7 +438,8 @@
             }
 
             detailsVo.setGoodName(pmdsServiceById.getName());
-            detailsVo.setStartTime(simpleDateFormat.format(pmdsServiceById.getStartTime()));
+            // 2.0
+            detailsVo.setStartTime(simpleDateFormat.format(byId.getInsertTime()));
             detailsVo.setEndTime(simpleDateFormat.format(pmdsServiceById.getEndTime()));
             detailsVo.setOrderTime(simpleDateFormat.format(byId.getInsertTime()));
             if (byId.getStatus() == 1){
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
index b1d407f..ad681fb 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/controller/UserCouponController.java
@@ -8,6 +8,7 @@
 import com.dsh.activity.feignclient.model.CouponStuAvailableVo;
 import com.dsh.activity.feignclient.model.QueryUserCouponByIdAndUserId;
 import com.dsh.activity.model.CouponListVo;
+import com.dsh.activity.model.SendCouponReq;
 import com.dsh.activity.service.CouponStoreService;
 import com.dsh.activity.service.ICouponService;
 import com.dsh.activity.service.UserCouponService;
@@ -22,6 +23,7 @@
 
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -94,6 +96,16 @@
         return cService.queryConponRuleOfJson(couponId);
     }
 
+    @ResponseBody
+    @PostMapping("/base/userConpon/getCoupons")
+    public List<Coupon> getCoupons(@RequestBody String couponIds){
+        ArrayList<Integer> integers = new ArrayList<>();
+        for (String s : couponIds.split(",")) {
+            Integer integer = Integer.valueOf(s);
+            integers.add(integer);
+        }
+        return cService.list(new LambdaQueryWrapper<Coupon>().in(Coupon::getId,integers));
+    }
 
 
     @ResponseBody
@@ -167,6 +179,23 @@
         }
     }
 
+    @PostMapping("/userCoupon/sendUserCoupon")
+    public void sendUserCoupon(@RequestBody SendCouponReq sendCouponReq){
+        try {
+            String couponIds = sendCouponReq.getCouponIds();
+            for (String s : couponIds.split(",")) {
+                UserCoupon userCoupon = new UserCoupon();
+                userCoupon.setCouponId(Integer.valueOf(s));
+                userCoupon.setUserId(sendCouponReq.getUserId());
+                userCoupon.setStatus(1);
+                userCoupon.setInsertTime(new Date());
+                userCouponService.save(userCoupon);
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
 
     /**
      * 修改优惠券数据
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java b/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java
index 017a237..a636b6d 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/entity/PointsMerchandise.java
@@ -163,6 +163,8 @@
      */
     @TableField("shelves")
     private Integer shelves;
+    @TableField("cardTye")
+    private Integer cardTye;
 
     @Override
     protected Serializable pkVal() {
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
index 9949082..621dfbc 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/PointDetailsVo.java
@@ -59,4 +59,6 @@
     @ApiModelProperty(value = "兑换方式(1=积分,2=积分+现金)")
     private Integer exchangeType;
 
+    private Integer cardType;
+
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/ProductDetailsVo.java b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/ProductDetailsVo.java
index 5fe6f2e..d53a2b3 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/ProductDetailsVo.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/feignclient/model/ProductDetailsVo.java
@@ -65,4 +65,7 @@
     @ApiModelProperty(value = "商品类型 1实物 2课包 3门票 4优惠券")
     private Integer goodType;
 
+    @ApiModelProperty(value = "1日卡 2月卡 3季卡 4年卡")
+    private Integer cardType;
+
 }
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/BenefitsVideosService.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/BenefitsVideosService.java
index 49cf43f..a4602ad 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/BenefitsVideosService.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/BenefitsVideosService.java
@@ -25,6 +25,7 @@
      * @throws Exception
      */
     List<BenefitsVideoClassificationListVo> queryClassificationBenefitsVideosList(Integer uid, Integer position, String search) throws Exception;
+    List<BenefitsVideoClassificationListVo> queryClassificationBenefitsVideosListOne(Integer uid, Integer position, String search) throws Exception;
 
 
     /**
diff --git a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/BenefitsVideosServiceImpl.java b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/BenefitsVideosServiceImpl.java
index 54e5111..f80ffc2 100644
--- a/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/BenefitsVideosServiceImpl.java
+++ b/cloud-server-activity/src/main/java/com/dsh/activity/service/impl/BenefitsVideosServiceImpl.java
@@ -103,6 +103,42 @@
         }
         return listVos;
     }
+    @Override
+    public List<BenefitsVideoClassificationListVo> queryClassificationBenefitsVideosListOne(Integer uid, Integer position, String search) throws Exception {
+        QueryWrapper<BenefitsVideoClassification> wrapper = new QueryWrapper<BenefitsVideoClassification>().eq("position", position);
+        if(ToolUtil.isNotEmpty(search)){
+            wrapper.like("name", search);
+        }
+        List<BenefitsVideoClassification> list = benefitsVideoClassificationService.list(wrapper.orderByAsc("sort"));
+        List<UserBenefitsVideos> userBenefitsVideos = userBenefitsVideosService.list(new QueryWrapper<UserBenefitsVideos>().eq("appUserId", -1));
+        List<Integer> collect = userBenefitsVideos.stream().map(UserBenefitsVideos::getBenefitsVideosId).collect(Collectors.toList());
+
+        List<BenefitsVideoClassificationListVo> listVos = new ArrayList<>();
+        for (BenefitsVideoClassification benefitsVideoClassification : list) {
+            BenefitsVideoClassificationListVo benefitsVideoClassificationListVo = new BenefitsVideoClassificationListVo();
+            benefitsVideoClassificationListVo.setId(benefitsVideoClassification.getId());
+            benefitsVideoClassificationListVo.setName(benefitsVideoClassification.getName());
+            QueryWrapper<BenefitsVideos> benefitsVideosQueryWrapper = new QueryWrapper<BenefitsVideos>().eq("state", 1);
+            if(collect.size() > 0){
+                benefitsVideosQueryWrapper.notIn("id", collect);
+            }
+            List<BenefitsVideos> list1 = this.list(benefitsVideosQueryWrapper.orderByDesc("insertTime").last(" limit 0, 4"));
+            List<BenefitsVideosListVo> lists = new ArrayList<>();
+            for (BenefitsVideos benefitsVideos : list1) {
+                Integer courseId = benefitsVideos.getCourseId();
+                Course course = courseClient.queryCourseById(courseId);
+                BenefitsVideosListVo benefitsVideosListVo = new BenefitsVideosListVo();
+                benefitsVideosListVo.setId(benefitsVideos.getId());
+                benefitsVideosListVo.setName(course.getName());
+                benefitsVideosListVo.setCover(course.getCoverDrawing());
+                benefitsVideosListVo.setIntroduce(course.getIntroduce());
+                lists.add(benefitsVideosListVo);
+            }
+            benefitsVideoClassificationListVo.setList(lists);
+            listVos.add(benefitsVideoClassificationListVo);
+        }
+        return listVos;
+    }
 
 
     @Override
diff --git a/cloud-server-auth/mb-cloud-auth.iml b/cloud-server-auth/mb-cloud-auth.iml
index 1daccae..13e8572 100644
--- a/cloud-server-auth/mb-cloud-auth.iml
+++ b/cloud-server-auth/mb-cloud-auth.iml
@@ -1,8 +1,2 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-</module>
\ No newline at end of file
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4" />
\ No newline at end of file
diff --git a/cloud-server-competition/mb-cloud-competition.iml b/cloud-server-competition/mb-cloud-competition.iml
index 1daccae..13e8572 100644
--- a/cloud-server-competition/mb-cloud-competition.iml
+++ b/cloud-server-competition/mb-cloud-competition.iml
@@ -1,8 +1,2 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-</module>
\ No newline at end of file
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4" />
\ No newline at end of file
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
index e82c819..f613014 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/controller/CompetitionController.java
@@ -204,6 +204,7 @@
     @ApiOperation(value = "赛事报名", tags = {"APP-赛事活动列表"})
     @ApiImplicitParams({
             @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+
     })
     public ResultUtil paymentCompetition(PaymentCompetitionVo paymentCompetitionVo){
         try {
@@ -217,6 +218,25 @@
             return ResultUtil.runErr();
         }
     }
+    @ResponseBody
+    @PostMapping("/api/competition/paymentCompetitionCourseList")
+    @ApiOperation(value = "赛事报名--支付可用课时列表", tags = {"APP-赛事活动列表"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+            @ApiImplicitParam(value = "赛事id", name = "id", dataType = "int", required = true),
+    })
+    public ResultUtil paymentCompetitionCourseList(Integer id){
+        try {
+            Integer uid = tokenUtil.getUserIdFormRedis();
+            if(null == uid){
+                return ResultUtil.tokenErr();
+            }
+            return cttService.paymentCompetitionCourseList(uid, id);
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
 
 
     /**
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/entity/Competition.java b/cloud-server-competition/src/main/java/com/dsh/competition/entity/Competition.java
index 100aa2e..8ff9be6 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/entity/Competition.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/entity/Competition.java
@@ -59,7 +59,7 @@
      * 门店id
      */
     @TableField("storeId")
-    private Integer storeId;
+    private String storeId;
     /**
      * 赛事名称
      */
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/CoursePackagePaymentClient.java b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/CoursePackagePaymentClient.java
index 6bad81e..184cd77 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/CoursePackagePaymentClient.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/CoursePackagePaymentClient.java
@@ -1,8 +1,12 @@
 package com.dsh.competition.feignclient.course;
 
 import com.dsh.competition.feignclient.course.model.PaymentDeductionClassHour;
+import com.dsh.competition.model.PayCourseRes;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
 
 /**
  * @author zhibing.pu
@@ -21,6 +25,10 @@
     Integer queryResidueClassHour(Integer id);
 
 
+    @PostMapping("/coursePackagePayment/queryResidueClassHourById")
+    Integer queryResidueClassHourById(Long id);
+
+
     /**
      * 支付扣减学员课时
      */
@@ -34,4 +42,9 @@
      */
     @PostMapping("/coursePackagePayment/rollbackPaymentDeductionClassHour")
     void rollbackPaymentDeductionClassHour(PaymentDeductionClassHour paymentDeductionClassHour);
+
+    @PostMapping("/coursePackagePayment/paymentCompetitionCourseList")
+    List<PayCourseRes> paymentCompetitionCourseList(String s);
+
+
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/model/PaymentDeductionClassHour.java b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/model/PaymentDeductionClassHour.java
index eb83edf..e8dc41d 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/model/PaymentDeductionClassHour.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/feignclient/course/model/PaymentDeductionClassHour.java
@@ -20,4 +20,8 @@
      * 支付编号
      */
     private String code;
+    /**
+     * 用于支付的课程
+     */
+    private Long courseId;
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionInfo.java b/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionInfo.java
index bbc3cc6..bd251ec 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionInfo.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/model/CompetitionInfo.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * @author zhibing.pu
@@ -67,4 +68,6 @@
     private Double payMoney;
     @ApiModelProperty("支付方式(1=微信,2=支付宝,3=玩湃币,4=课时)")
     private Integer payType;
+    @ApiModelProperty("门店信息")
+    private List<Map<String,Object>> storeInfos;
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/model/PaymentCompetitionVo.java b/cloud-server-competition/src/main/java/com/dsh/competition/model/PaymentCompetitionVo.java
index 0d0a6d5..e03bd06 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/model/PaymentCompetitionVo.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/model/PaymentCompetitionVo.java
@@ -17,4 +17,6 @@
     private String ids;
     @ApiModelProperty(value = "支付方式(1=微信,2=支付宝,3=余额,4=课时)", dataType = "int", required = true)
     private Integer payType;
+    @ApiModelProperty(value = "我的购买课包id")
+    private Long coursePaymentId;
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
index 85cdbdd..61efa07 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/CompetitionService.java
@@ -53,4 +53,14 @@
      * 定时任务修改赛事状态
      */
     void taskSetStatus();
+
+    /**
+     * 赛事可用课包
+     * @param uid
+     * @param id
+     * @return
+     */
+    ResultUtil paymentCompetitionCourseList(Integer uid, Integer id);
+
+
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
index 74c35c7..77267b3 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/CompetitionServiceImpl.java
@@ -16,10 +16,7 @@
 import com.dsh.competition.feignclient.other.StoreClient;
 import com.dsh.competition.feignclient.other.model.Store;
 import com.dsh.competition.mapper.CompetitionMapper;
-import com.dsh.competition.model.CompetitionInfo;
-import com.dsh.competition.model.CompetitionListVo;
-import com.dsh.competition.model.ParticipantVo;
-import com.dsh.competition.model.PaymentCompetitionVo;
+import com.dsh.competition.model.*;
 import com.dsh.competition.service.CompetitionService;
 import com.dsh.competition.service.IParticipantService;
 import com.dsh.competition.service.IPaymentCompetitionService;
@@ -32,10 +29,7 @@
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -104,19 +98,30 @@
         competitionInfo.setImgs(competition.getImgs());
         competitionInfo.setName(competition.getName());
         competitionInfo.setRegisterCondition(competition.getRegisterCondition());
+
+        // 2.0
+        ArrayList<Map<String,Object>> objects = new ArrayList<>();
         if(null != competition.getStoreId()){
-            Store store = storeClient.queryStoreById(competition.getStoreId());
-            competitionInfo.setStoreName(store.getName());
-            competitionInfo.setStoreAddress(store.getAddress());
-            competitionInfo.setStoreLon(store.getLon());
-            competitionInfo.setStoreLat(store.getLat());
-            competitionInfo.setStoreCoverDrawing(store.getCoverDrawing());
-            if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){
-                Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
-                double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
-                competitionInfo.setDistance(wgs84);
+            HashMap<String, Object> map = new HashMap<>();
+            String storeId = competition.getStoreId();
+            for (String s : storeId.split(",")) {
+                Store store = storeClient.queryStoreById(Integer.valueOf(s));
+                map.put("name",store.getName());
+                map.put("address",store.getAddress());
+                map.put("storeLon",store.getLon());
+                map.put("storeLat",store.getLat());
+                map.put("storeCoverDrawing",store.getCoverDrawing());
+                if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){
+                    Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
+                    double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
+                    map.put("distance",wgs84);
+                }
             }
+            objects.add(map);
         }
+        competitionInfo.setStoreInfos(objects);
+
+
         competitionInfo.setRegisterEndTime(sdf.format(competition.getRegisterEndTime()));
         competitionInfo.setStartTime(sdf.format(competition.getStartTime()));
         competitionInfo.setEndTime(sdf.format(competition.getEndTime()));
@@ -187,7 +192,8 @@
                 if(null == student){
                     return ResultUtil.error(participant.getName() + "不是学员,无法使用课时支付。");
                 }
-                Integer integer = coursePackagePaymentClient.queryResidueClassHour(student.getId());
+                // 2.0
+                Integer integer = coursePackagePaymentClient.queryResidueClassHourById(paymentCompetitionVo.getCoursePaymentId());
                 if(new BigDecimal(integer).compareTo(new BigDecimal(competition.getClassPrice())) < 0){
                     return ResultUtil.error(participant.getName() + "剩余课时不足,无法完成支付。");
                 }
@@ -245,6 +251,7 @@
                 paymentDeductionClassHour.setId(student.getId());
                 paymentDeductionClassHour.setClassHour(competition.getClassPrice());
                 paymentDeductionClassHour.setCode(code);
+                paymentDeductionClassHour.setCourseId(paymentCompetitionVo.getCoursePaymentId());
                 coursePackagePaymentClient.paymentDeductionClassHour(paymentDeductionClassHour);
             }
             paymentCompetition = paymentCompetitionService.getById(paymentCompetition.getId());
@@ -400,4 +407,14 @@
         this.baseMapper.taskSetStatusStart();
         this.baseMapper.taskSetStatusEnd();
     }
+
+    @Override
+    public ResultUtil paymentCompetitionCourseList(Integer uid, Integer id) {
+        Competition competition = this.baseMapper.selectById(id);
+        // 获取门店id  找出符合这些门店的课包
+        String storeId = competition.getStoreId();
+
+        List<PayCourseRes> list = coursePackagePaymentClient.paymentCompetitionCourseList(uid+"_"+storeId);
+        return ResultUtil.success(list);
+    }
 }
diff --git a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java
index fbde07c..3f62769 100644
--- a/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java
+++ b/cloud-server-competition/src/main/java/com/dsh/competition/service/impl/PaymentCompetitionServiceImpl.java
@@ -106,7 +106,7 @@
         competitionInfo.setImgs(competition.getImgs());
         competitionInfo.setName(competition.getName());
         competitionInfo.setRegisterCondition(competition.getRegisterCondition());
-        Store store = storeClient.queryStoreById(competition.getStoreId());
+        Store store = storeClient.queryStoreById(Integer.valueOf(competition.getStoreId().split(",")[0]));
         competitionInfo.setStoreName(store.getName());
         competitionInfo.setStoreAddress(store.getAddress());
         competitionInfo.setStoreLon(store.getLon());
diff --git a/cloud-server-course/mb-cloud-course.iml b/cloud-server-course/mb-cloud-course.iml
index 1daccae..5890c76 100644
--- a/cloud-server-course/mb-cloud-course.iml
+++ b/cloud-server-course/mb-cloud-course.iml
@@ -1,8 +1,18 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
+<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" version="4">
   <component name="FacetManager">
     <facet type="Spring" name="Spring">
       <configuration />
     </facet>
+    <facet type="jpa" name="JPA">
+      <configuration>
+        <setting name="validation-enabled" value="true" />
+        <setting name="provider-name" value="Hibernate" />
+        <datasource-mapping>
+          <factory-entry name="entityManagerFactory" />
+        </datasource-mapping>
+        <naming-strategy-map />
+      </configuration>
+    </facet>
   </component>
 </module>
\ No newline at end of file
diff --git a/cloud-server-course/src/main/java/com/dsh/course/controller/CourseController.java b/cloud-server-course/src/main/java/com/dsh/course/controller/CourseController.java
index f885da2..d23a26e 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/controller/CourseController.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/controller/CourseController.java
@@ -134,7 +134,6 @@
 
 
 
-
     @ResponseBody
     @PostMapping("/api/course/queryCourseList")
     @ApiOperation(value = "获取课程列表", tags = {"APP-课程列表"})
@@ -148,6 +147,23 @@
                 return ResultUtil.tokenErr();
             }
             List<CoursePackageListVo> coursePackageListVos = coursePackageService.queryCourseList(uid, coursePackageList);
+            return ResultUtil.success(coursePackageListVos);
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
+
+    @ResponseBody
+    @PostMapping("/base/course/queryCourseListOne")
+    @ApiOperation(value = "获取课程列表", tags = {"APP-课程列表"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResultUtil<List<CoursePackageListVo>> queryCourseListOne(CoursePackageList coursePackageList){
+        try {
+            List<CoursePackageListVo> coursePackageListVos = coursePackageService.queryCourseListOne( coursePackageList);
             return ResultUtil.success(coursePackageListVos);
         }catch (Exception e){
             e.printStackTrace();
@@ -203,6 +219,26 @@
         }
     }
 
+    // 2.0
+    @ResponseBody
+    @PostMapping("/api/course/paymentCourseCouponList")
+    @ApiOperation(value = "支付课程--完成后优惠券列表", tags = {"APP-课程列表"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
+    })
+    public ResultUtil paymentCourseCouponList(Integer coursePackagePaymentConfigId){
+        try {
+            Integer uid = tokenUtil.getUserIdFormRedis();
+            if(null == uid){
+                return ResultUtil.tokenErr();
+            }
+            return coursePackageService.paymentCourseCouponList(uid, coursePackagePaymentConfigId);
+        }catch (Exception e){
+            e.printStackTrace();
+            return ResultUtil.runErr();
+        }
+    }
+
 
     /**
      * 购买课程微信支付回调
diff --git a/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java b/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java
index a5bbd2e..c350bf2 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/controller/CoursePackagePaymentController.java
@@ -1,6 +1,8 @@
 package com.dsh.course.controller;
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -9,6 +11,7 @@
 import com.dsh.course.feignclient.account.StudentClient;
 import com.dsh.course.feignclient.account.model.AppUser;
 import com.dsh.course.feignclient.account.model.Student;
+import com.dsh.course.feignclient.account.model.TCourseInfoRecord;
 import com.dsh.course.feignclient.model.*;
 import com.dsh.course.feignclient.other.StoreClient;
 import com.dsh.course.feignclient.other.model.Store;
@@ -21,9 +24,7 @@
 import com.dsh.course.model.vo.CourseDetailRequest;
 import com.dsh.course.model.vo.RegisterCourseVo;
 import com.dsh.course.model.vo.request.*;
-import com.dsh.course.model.vo.response.AppUserVideoResponse;
-import com.dsh.course.model.vo.response.CourseDetailsResponse;
-import com.dsh.course.model.vo.response.CourseOfVideoResponse;
+import com.dsh.course.model.vo.response.*;
 import com.dsh.course.service.*;
 import com.dsh.course.util.*;
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -36,7 +37,10 @@
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
@@ -102,6 +106,13 @@
 
     @Resource
     private StoreClient sreClient;
+
+    @Autowired
+    private AppUserClient appUserClient;
+
+    @Autowired
+    private RestTemplate internalRestTemplate;
+
 
     private final SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm");
 
@@ -185,6 +196,11 @@
                             storeVo.setLon(store.getLon());
                             storeVo.setCoursePrice(ToolUtil.isEmpty(paymentConfig.getCashPayment()) ? (double) paymentConfig.getPlayPaiCoin():paymentConfig.getCashPayment());
                             storeVo.setStatus(1);
+                            // 2.0
+                            storeVo.setAllNum(tCoursePackagePayment.getTotalClassHours());
+                            storeVo.setLastNum(tCoursePackagePayment.getLaveClassHours());
+                            storeVo.setUseNum(tCoursePackagePayment.getTotalClassHours()-tCoursePackagePayment.getLaveClassHours());
+
                             course.add(storeVo);
                         }
                     }
@@ -484,6 +500,59 @@
     }
 
 
+    @ResponseBody
+    @PostMapping("/api/startCource/payCourseInfo")
+    @ApiOperation(value = "课后练习-购课详情(用于购课)", tags = {"APP-开始上课"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+    })
+    public ResultUtil<PayCourseInfoReq> payCourseInfo(Integer courseId){
+        try {
+            return ResultUtil.success(packagePaymentService.payCourseInfo(courseId));
+        }catch (Exception e){
+            return ResultUtil.runErr();
+        }
+    }
+
+
+    @ResponseBody
+    @PostMapping("/api/startCource/getMyCourseList")
+    @ApiOperation(value = "课后练习-可支付课程列表(用于购课)", tags = {"APP-开始上课"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+    })
+    public ResultUtil<List<PayCourseRes>> getMyCourseList(Integer storeId){
+        try {
+            Integer appUserId = tokenUtil.getUserIdFormRedis();
+            if(null == appUserId){
+                return ResultUtil.tokenErr();
+            }
+            return ResultUtil.success(packagePaymentService.getMyCourseList(storeId,appUserId));
+        }catch (Exception e){
+            return ResultUtil.runErr();
+        }
+    }
+
+    // 2.0
+    @ResponseBody
+    @PostMapping("/api/startCource/payCourse")
+    @ApiOperation(value = "课后练习-确认购课", tags = {"APP-开始上课"})
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
+    })
+    public ResultUtil<?> payCourse(@RequestBody PayCourseReq req){
+        try {
+            Integer appUserId = tokenUtil.getUserIdFormRedis();
+            if(null == appUserId){
+                return ResultUtil.tokenErr();
+            }
+            return packagePaymentService.payCourse(req,appUserId);
+        }catch (Exception e){
+            return ResultUtil.runErr();
+        }
+    }
+
+
     /**
      * 更新课后视频学习状态
      */
@@ -671,6 +740,22 @@
             return 0;
         }
     }
+    /**
+     * 获取学员剩余课时
+     * @param id
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/coursePackagePayment/queryResidueClassHourById")
+    public Integer queryResidueClassHourById(@RequestBody Long id){
+        try {
+            TCoursePackagePayment list = packagePaymentService.getById(id);
+            return list.getLaveClassHours();
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+    }
 
 
     /**
@@ -681,13 +766,31 @@
     @PostMapping("/coursePackagePayment/paymentDeductionClassHour")
     public void paymentDeductionClassHour(@RequestBody PaymentDeductionClassHour paymentDeductionClassHour){
         try {
-            List<TCoursePackagePayment> list = packagePaymentService.list(new QueryWrapper<TCoursePackagePayment>().eq("studentId", paymentDeductionClassHour.getId()).eq("payStatus", 2)
+            // 2.0 用id进行查询
+            List<TCoursePackagePayment> list = packagePaymentService.list(new QueryWrapper<TCoursePackagePayment>().eq("id", paymentDeductionClassHour.getCourseId()).eq("payStatus", 2)
                     .eq("status", 1).eq("state", 1).gt("laveClassHours", 0));
             Integer classHour = paymentDeductionClassHour.getClassHour();
             for (TCoursePackagePayment coursePackagePayment : list) {
                 if(coursePackagePayment.getLaveClassHours().compareTo(classHour) >= 0){
                     coursePackagePayment.setLaveClassHours(coursePackagePayment.getLaveClassHours() - classHour);
                     packagePaymentService.updateById(coursePackagePayment);
+
+                    // 2.0 少于3课时 推送
+                    if(coursePackagePayment.getLaveClassHours()<=3){
+                        Integer appUserId = coursePackagePayment.getAppUserId();
+
+                        //调用推送
+                        HttpHeaders headers = new HttpHeaders();
+                        // 以表单的方式提交
+                        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+                        String s1 = appUserId + "_" + "Three";
+                        //定时修改排课状态
+                        String s = internalRestTemplate.getForObject("http://mb-cloud-gateway/netty/sendMsgToClient?id="+s1, String.class);
+                        JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
+                        if(jsonObject1.getIntValue("code") != 200){
+                            System.err.println(jsonObject1.getString("msg"));
+                        }
+                    }
 
                     CancelledClasses cancelledClasses = new CancelledClasses();
                     cancelledClasses.setType(2);
@@ -743,6 +846,42 @@
 
 
     /**
+     * 找出符合门店的课包
+     * @param s
+     * @return
+     */
+    @ResponseBody
+    @PostMapping("/coursePackagePayment/paymentCompetitionCourseList")
+    public List<PayCourseRes> paymentCompetitionCourseList(@RequestBody String s){
+        ArrayList<PayCourseRes> objects = new ArrayList<>();
+
+        String[] split = s.split("_");
+        // 用户id
+        Integer integer = Integer.valueOf(split[0]);
+        String s1 = split[1];
+        // 门店id
+        String[] split1 = s1.split(",");
+        ArrayList<Integer> storeIds = new ArrayList<>();
+        for (String s2 : split1) {
+            storeIds.add(Integer.valueOf(s2));
+        }
+        List<TCoursePackagePayment> list = packagePaymentService.list(new LambdaQueryWrapper<TCoursePackagePayment>().eq(TCoursePackagePayment::getAppUserId, integer).ge(TCoursePackagePayment::getLaveClassHours, 0).eq(TCoursePackagePayment::getStatus, 1).eq(TCoursePackagePayment::getState, 1));
+        for (TCoursePackagePayment tCoursePackagePayment : list) {
+            Integer coursePackageId = tCoursePackagePayment.getCoursePackageId();
+            TCoursePackage byId = tcpService.getById(coursePackageId);
+            if(storeIds.contains(byId.getStoreId())){
+                PayCourseRes payCourseRes = new PayCourseRes();
+                payCourseRes.setCourseNum(tCoursePackagePayment.getLaveClassHours());
+                payCourseRes.setId(tCoursePackagePayment.getId());
+                payCourseRes.setName(byId.getName());
+                objects.add(payCourseRes);
+            }
+        }
+        return objects;
+    }
+
+
+    /**
      * 课包续费玩湃币支付
      * @param
      */
@@ -770,6 +909,16 @@
 
             appUser.setPlayPaiCoins(appUser.getPlayPaiCoins()-paymentConfig.getPlayPaiCoin());
             auClitn.updateAppUser(appUser);
+
+            // 2.0
+            TCourseInfoRecord tCourseInfoRecord = new TCourseInfoRecord();
+            tCourseInfoRecord.setUserId(userIdFormRedis);
+            tCourseInfoRecord.setCourseId(coursePackage.getCoursePackageId());
+            tCourseInfoRecord.setName("续课");
+            tCourseInfoRecord.setTime(new Date());
+            tCourseInfoRecord.setType(1);
+            tCourseInfoRecord.setNum(paymentConfig.getClassHours());
+            auClitn.addCourseInfoRecord(tCourseInfoRecord);
         } catch (Exception e) {
             return 4;
         }
@@ -788,8 +937,20 @@
     }
     @PostMapping("/base/coursePack/updatePaymentCoursePackage")
     public boolean updatePaymentCoursePackage(@RequestBody TCoursePackagePayment packagePayment){
-        return packagePaymentService.update(packagePayment,new QueryWrapper<TCoursePackagePayment>()
-                .eq("id",packagePayment.getId()));
+        boolean id = packagePaymentService.update(packagePayment, new QueryWrapper<TCoursePackagePayment>()
+                .eq("id", packagePayment.getId()));
+        if(id){
+            // 2.0
+            TCourseInfoRecord tCourseInfoRecord = new TCourseInfoRecord();
+            tCourseInfoRecord.setNum(packagePayment.getTotalClassHours());
+            tCourseInfoRecord.setName("续课");
+            tCourseInfoRecord.setCourseId(packagePayment.getCoursePackageId());
+            tCourseInfoRecord.setUserId(packagePayment.getAppUserId());
+            tCourseInfoRecord.setType(1);
+            tCourseInfoRecord.setTime(new Date());
+            id = appUserClient.addCourseInfoRecord(tCourseInfoRecord);
+        }
+        return id;
     }
 
     @PostMapping("/base/coursePack/savePaymentCoursePackage")
@@ -824,6 +985,27 @@
                 .eq("code",code));
     }
 
+
+    // 2.0 送课时
+    @PostMapping("/base/coursePack/sendHours")
+    public Boolean sendHours(@RequestBody  String s){
+        String[] split = s.split("_");
+        TCoursePackagePayment byId = packagePaymentService.getById(Integer.valueOf(split[0]));
+        byId.setTotalClassHours(byId.getTotalClassHours()+Integer.valueOf(split[2]));
+        return packagePaymentService.updateById(byId);
+    }
+
+
+    /**
+     * 查询课时
+     * @param courseConfigId
+     * @return
+     */
+    @PostMapping("/base/coursePack/getClassHour")
+    public Integer getClassHour(@RequestBody Integer courseConfigId){
+        CoursePackagePaymentConfig byId = icppcService.getById(courseConfigId);
+        return byId.getClassHours();
+    }
 
     /**
      * 获取课包报名信息列表
@@ -881,7 +1063,7 @@
      */
     @ResponseBody
     @PostMapping("/api/startCource/reverse")
-    @ApiOperation(value = "上课主页-预约操作", tags = {"APP-开始上课"})
+    @ApiOperation(value = "上课主页-预约操作--2.0改请假操作", tags = {"APP-开始上课"})
     @ApiImplicitParams({
             @ApiImplicitParam(name = "Authorization", value = "Bearer +token", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9....."),
             @ApiImplicitParam(value = "课包id", name = "courseID", required = true, dataType = "String"),
@@ -912,7 +1094,7 @@
             );
 
             if (ToolUtil.isNotEmpty(coursePackageStudent) && coursePackageStudent.getReservationStatus() == 0){
-                coursePackageStudent.setReservationStatus(1);
+                coursePackageStudent.setSignInOrNot(2);
                 coursePackageStudent.setInsertTime(simpleDateFormat.parse(time));
                 cspsService.updateById(coursePackageStudent);
             }else {
@@ -921,7 +1103,7 @@
                 coursePackageStudent.setStudentId(stuId);
                 coursePackageStudent.setCoursePackageId(packagePayment.getCoursePackageId());
                 coursePackageStudent.setCoursePackagePaymentId(Long.parseLong(courseID));
-                coursePackageStudent.setReservationStatus(1);
+                coursePackageStudent.setSignInOrNot(2);
                 coursePackageStudent.setInsertTime(simpleDateFormat.parse(time));
                 cspsService.save(coursePackageStudent);
             }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackagePaymentConfig.java b/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackagePaymentConfig.java
index 1b9c125..41ad552 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackagePaymentConfig.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/entity/CoursePackagePaymentConfig.java
@@ -38,4 +38,6 @@
      */
     @TableField("playPaiCoin")
     private Integer playPaiCoin;
+    @TableField("couponIds")
+    private String couponIds;
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/entity/TCoursePackage.java b/cloud-server-course/src/main/java/com/dsh/course/entity/TCoursePackage.java
index 5eddca4..96faab9 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/entity/TCoursePackage.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/entity/TCoursePackage.java
@@ -159,5 +159,9 @@
     @TableField("insertTime")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date insertTime;
+    @TableField("type")
+    private Integer type;
+    @TableField("needNum")
+    private Integer needNum;
 
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/account/AppUserClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/account/AppUserClient.java
index ccfb109..7f68da6 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/account/AppUserClient.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/account/AppUserClient.java
@@ -1,6 +1,7 @@
 package com.dsh.course.feignclient.account;
 
 import com.dsh.course.feignclient.account.model.AppUser;
+import com.dsh.course.feignclient.account.model.TCourseInfoRecord;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
 
@@ -37,4 +38,10 @@
      */
     @PostMapping("/appUser/queryAppUserListByName")
     List<AppUser> queryAppUserListByName(String name);
+
+
+    @PostMapping("/appUser/addCourseInfoRecord")
+    Boolean addCourseInfoRecord(TCourseInfoRecord tCourseInfoRecord);
+
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java
index 14d78a6..133f103 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/CouponClient.java
@@ -5,6 +5,7 @@
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -25,4 +26,9 @@
 
     @PostMapping("/base/userConpon/queryCouponRules")
     Map<String,Object> getCouponRules(@RequestBody Integer couponId);
+
+    @PostMapping("/base/userConpon/getCoupons")
+    List<Coupon> getCoupons(String couponIds);
+
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/UserCouponClient.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/UserCouponClient.java
index 4e4b546..704dc64 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/UserCouponClient.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/activity/UserCouponClient.java
@@ -1,5 +1,6 @@
 package com.dsh.course.feignclient.activity;
 
+import com.dsh.course.feignclient.activity.model.SendCouponReq;
 import com.dsh.course.feignclient.activity.model.UserCoupon;
 import org.springframework.cloud.openfeign.FeignClient;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -19,4 +20,11 @@
      */
     @PostMapping("/userCoupon/queryUserCouponById")
     UserCoupon queryUserCouponById(Long id);
+
+    /**
+     * 送优惠券
+     * @param sendCouponReq
+     */
+    @PostMapping("/userCoupon/sendUserCoupon")
+    void sendUserCoupon(SendCouponReq sendCouponReq);
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/CourseOfStoreVo.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/CourseOfStoreVo.java
index b2ca79c..9fe5fe3 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/CourseOfStoreVo.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/CourseOfStoreVo.java
@@ -36,4 +36,12 @@
 
     @ApiModelProperty(value = "预约状态")
     private Integer status;
+
+    @ApiModelProperty(value = "总学时数")
+    Integer allNum;
+    @ApiModelProperty(value = "已扣学时数")
+    Integer useNum;
+    @ApiModelProperty(value = "剩余学时数")
+    Integer lastNum;
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/PaymentDeductionClassHour.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/PaymentDeductionClassHour.java
index e472cf5..0953dd1 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/PaymentDeductionClassHour.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/PaymentDeductionClassHour.java
@@ -20,4 +20,8 @@
      * 支付编号
      */
     private String code;
+    /**
+     * 用于支付的课程
+     */
+    private Long courseId;
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/RecordAppoint.java b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/RecordAppoint.java
index ca6a2cf..49d1ffc 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/RecordAppoint.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/feignclient/model/RecordAppoint.java
@@ -24,7 +24,7 @@
     @ApiModelProperty(value = "门店名称+地址")
     private String storeNameAddr;
 
-    @ApiModelProperty(value = "课状态(1待上课 2已开始 3已完成 4已取消)")
+    @ApiModelProperty(value = "课状态(1待上课 2已开始 3已完成 4已取消 5已请假 6旷课)")
     private Integer status;
 
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageInfo.java b/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageInfo.java
index 82469df..18538e3 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageInfo.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageInfo.java
@@ -34,7 +34,7 @@
     @ApiModelProperty("上课周")
     private List<String> weeks;
     @ApiModelProperty("上课时间")
-    private String times;
+    private List<String> times;
     @ApiModelProperty("详情图片")
     private String detailDrawing;
     @ApiModelProperty("介绍图")
@@ -43,4 +43,6 @@
     private List<CoursePackagePaymentConfigVo> list;
     @ApiModelProperty("学员")
     private StudentVo student;
+    @ApiModelProperty("1常规 2假期 3体验")
+    private Integer type;
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageListVo.java b/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageListVo.java
index e9da1da..315b45c 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageListVo.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/model/CoursePackageListVo.java
@@ -4,6 +4,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * @author zhibing.pu
  * @date 2023/6/24 17:34
@@ -20,7 +22,7 @@
     @ApiModelProperty("封面图")
     private String coverDrawing;
     @ApiModelProperty("上课时间")
-    private String classStartTime;
+    private List<String> classStartTime;
     @ApiModelProperty("已报名人数")
     private Integer applicantsNumber;
     @ApiModelProperty("支付方式(1=现金,2=玩湃币)")
@@ -35,4 +37,6 @@
     private Integer playPaiCoin;
     @ApiModelProperty("距离")
     private Double distance;
+    @ApiModelProperty("1常规 2假期 3体验")
+    private Integer type;
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/model/vo/RegisterCourseVo.java b/cloud-server-course/src/main/java/com/dsh/course/model/vo/RegisterCourseVo.java
index ba888d3..877a839 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/model/vo/RegisterCourseVo.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/model/vo/RegisterCourseVo.java
@@ -34,4 +34,7 @@
     @ApiModelProperty(value = "课包类型id")
     private Integer coursePackTypeId;
 
+    @ApiModelProperty(value = "1常规 2假期 3体验")
+    private Integer type;
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java
index cd0703d..17f21f8 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackagePaymentService.java
@@ -1,5 +1,6 @@
 package com.dsh.course.service;
 
+import com.baomidou.mybatisplus.extension.api.R;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.dsh.course.entity.TCoursePackagePayment;
@@ -8,13 +9,8 @@
 import com.dsh.course.model.QueryWalkInStudentList;
 import com.dsh.course.model.BillingRequest;
 import com.dsh.course.model.vo.RegisterCourseVo;
-import com.dsh.course.model.vo.request.ClasspaymentRequest;
-import com.dsh.course.model.vo.request.CourseOfAfterRequest;
-import com.dsh.course.model.vo.request.CourseWithDetailsRequest;
-import com.dsh.course.model.vo.request.UpdateCourseVideoStatusRequest;
-import com.dsh.course.model.vo.response.AppUserVideoResponse;
-import com.dsh.course.model.vo.response.CourseDetailsResponse;
-import com.dsh.course.model.vo.response.CourseOfVideoResponse;
+import com.dsh.course.model.vo.request.*;
+import com.dsh.course.model.vo.response.*;
 import com.dsh.course.util.ResultUtil;
 
 import java.util.List;
@@ -112,4 +108,14 @@
      * @return
      */
     List<Map<String, Object>> queryWalkInStudentList(Page<Map<String, Object>> page, QueryWalkInStudentList queryWalkInStudentList);
+
+    List<PayCourseRes> getMyCourseList(Integer storeId, Integer appUserId);
+
+
+    PayCourseInfoReq payCourseInfo(Integer courseId);
+
+
+    ResultUtil payCourse(PayCourseReq req, Integer userId);
+
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java
index 4708c1c..672f810 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/service/TCoursePackageService.java
@@ -89,4 +89,11 @@
 
     String getHours(Integer coursePackageId);
 
+    ResultUtil paymentCourseCouponList(Integer uid, Integer coursePackagePaymentConfigId);
+
+
+    List<CoursePackageListVo> queryCourseListOne(CoursePackageList coursePackageList) throws Exception;
+
+
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java
index 8d2bccb..4e7fbbd 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackagePaymentServiceImpl.java
@@ -14,6 +14,7 @@
 import com.dsh.course.feignclient.account.model.AppUser;
 import com.dsh.course.feignclient.account.model.Coach;
 import com.dsh.course.feignclient.account.model.Student;
+import com.dsh.course.feignclient.account.model.TCourseInfoRecord;
 import com.dsh.course.feignclient.activity.BenefitVideoClient;
 import com.dsh.course.feignclient.activity.CouponClient;
 import com.dsh.course.feignclient.activity.model.BenefitsVideos;
@@ -27,20 +28,20 @@
 import com.dsh.course.model.QueryWalkInStudentList;
 import com.dsh.course.model.dto.DiscountJsonDto;
 import com.dsh.course.model.vo.RegisterCourseVo;
-import com.dsh.course.model.vo.request.ClasspaymentRequest;
-import com.dsh.course.model.vo.request.CourseOfAfterRequest;
-import com.dsh.course.model.vo.request.CourseWithDetailsRequest;
-import com.dsh.course.model.vo.request.UpdateCourseVideoStatusRequest;
-import com.dsh.course.model.vo.response.AppUserVideoResponse;
-import com.dsh.course.model.vo.response.CourseDetailsResponse;
-import com.dsh.course.model.vo.response.CourseOfVideoResponse;
+import com.dsh.course.model.vo.request.*;
+import com.dsh.course.model.vo.response.*;
 import com.dsh.course.service.ICoursePackageSchedulingService;
 import com.dsh.course.service.TCoursePackagePaymentService;
 import com.dsh.course.util.*;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
@@ -107,6 +108,10 @@
 
     @Autowired
     private ICoursePackageSchedulingService coursePackageSchedulingService;
+
+
+    @Autowired
+    private RestTemplate internalRestTemplate;
 
 
 
@@ -221,13 +226,18 @@
                 TCoursePackage coursePackage = tcpmapper.selectById(tCoursePackagePayment.getCoursePackageId());
                 Store store = stoClient.queryStoreById(coursePackage.getStoreId());
                 RegisterCourseVo registerCourseVo = new RegisterCourseVo();
+                // 2.0
+                registerCourseVo.setType(coursePackage.getType());
+
                 registerCourseVo.setCoursePayId(tCoursePackagePayment.getId());
                 registerCourseVo.setCoursePackageId(tCoursePackagePayment.getCoursePackageId());
                 registerCourseVo.setCoursePackTypeId(coursePackage.getCoursePackageTypeId());
                 registerCourseVo.setPackageImg(coursePackage.getCoverDrawing());
                 String storeAndCourse = coursePackage.getName()+"("+ store.getName() +")";
                 registerCourseVo.setCourseNameStore(storeAndCourse);
-                registerCourseVo.setCourseTime(coursePackage.getClassStartTime()+"-"+coursePackage.getClassEndTime());
+//                registerCourseVo.setCourseTime(coursePackage.getClassStartTime()+"-"+coursePackage.getClassEndTime());
+                // 2.0
+                registerCourseVo.setCourseTime(new SimpleDateFormat("yyyy-MM-dd").format(tCoursePackagePayment.getInsertTime()));
                 Coach coach = coachClient.queryCoachById(coursePackage.getCoachId());
                 registerCourseVo.setCourseTeacher(ToolUtil.isEmpty(coach) ? "" : coach.getName());
                 List<CoursePackageStudent> coursePackageStudents = cpsMapper.selectList(new QueryWrapper<CoursePackageStudent>()
@@ -602,7 +612,6 @@
                     String[] split = classWeeks.split(";");
                     List<String> integerList = Arrays.asList(split);
                     String weekOfDate = DateTimeHelper.getWeekOfDate(new Date());
-
                     if (integerList.contains(weekOfDate)){
                         String dat = simpleDateFormat.format(date) +" "+ classStartTime;
 
@@ -614,11 +623,18 @@
                         }
                         if (start.after(new Date())){
                             recordVo.setStatus(1);
+                        }else if(coursePackageStudent.getSignInOrNot()==2){
+                            recordVo.setStatus(5);
                         }else {
                             CancelledClasses cancelledClasses = cacMapper.selectOne(new QueryWrapper<CancelledClasses>()
                                     .eq("coursePackageId",tCoursePackagePayment.getCoursePackageId() ));
                             if (ToolUtil.isNotEmpty(cancelledClasses)){
                                 recordVo.setStatus(3);
+                                // 消课 到课状态0 旷课
+                                if(coursePackageStudent.getSignInOrNot()==0){
+                                    recordVo.setStatus(6);
+                                }
+
                             }else {
                                 recordVo.setStatus(2);
                             }
@@ -626,10 +642,10 @@
                     }else {
                         recordVo.setStatus(1);
                     }
+
                 }else {
                     recordVo.setStatus(4);
                 }
-
                 recordVoList.add(recordVo);
             }
         }
@@ -745,4 +761,154 @@
         }
         return list;
     }
+
+    @Override
+    public List<PayCourseRes> getMyCourseList(Integer storeId, Integer appUserId) {
+        // 找到购买的课包
+        List<TCoursePackagePayment> tCoursePackagePayments = this.baseMapper.selectList(new LambdaQueryWrapper<TCoursePackagePayment>().eq(TCoursePackagePayment::getAppUserId, appUserId));
+        ArrayList<PayCourseRes> payCourseRes = new ArrayList<>();
+        for (TCoursePackagePayment tCoursePackagePayment : tCoursePackagePayments) {
+            TCoursePackage tCoursePackage = tcpmapper.selectById(tCoursePackagePayment.getCoursePackageId());
+            if(tCoursePackage.getStoreId().equals(storeId)){
+                PayCourseRes payCourseRes1 = new PayCourseRes();
+                payCourseRes1.setId(tCoursePackagePayment.getId());
+                payCourseRes1.setName(tCoursePackage.getName());
+                payCourseRes1.setCourseNum(tCoursePackagePayment.getLaveClassHours());
+                payCourseRes.add(payCourseRes1);
+
+            }
+        }
+        return payCourseRes;
+    }
+
+    @Override
+    public PayCourseInfoReq payCourseInfo(Integer courseId){
+        PayCourseInfoReq payCourseInfoReq = new PayCourseInfoReq();
+        TCoursePackage tCoursePackage = tcpmapper.selectById(courseId);
+        payCourseInfoReq.setId(courseId);
+        payCourseInfoReq.setName(tCoursePackage.getName());
+        payCourseInfoReq.setNum(tCoursePackage.getNeedNum());
+        payCourseInfoReq.setWeek(tCoursePackage.getClassWeeks());
+        String classStartTime = tCoursePackage.getClassStartTime();
+        String classEndTime = tCoursePackage.getClassEndTime();
+        String[] split = classStartTime.split(",");
+        String[] split1 = classEndTime.split(",");
+        ArrayList<String> strings = new ArrayList<>();
+        for (int i = 0; i < classStartTime.split(",").length; i++) {
+            String s = split[i] + "-" + split1[i];
+            strings.add(s);
+        }
+        payCourseInfoReq.setTime(strings);
+        return payCourseInfoReq;
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
+    public ResultUtil payCourse(PayCourseReq req,Integer userId){
+        // 扣除 原来的课时数
+        // 添加购买课时 paytyoe为7
+        // 排课可期  判断课程时间段  添加排课表  添加上课记录表
+        // 找到原来的课包 扣课时
+        TCoursePackagePayment tCoursePackagePayment = this.baseMapper.selectById(req.getOldCourseId());
+        if(req.getNum()>tCoursePackagePayment.getLaveClassHours()){
+            return ResultUtil.error("当前课包课时数不足");
+        }
+        tCoursePackagePayment.setLaveClassHours(tCoursePackagePayment.getLaveClassHours()-req.getNum());
+        this.baseMapper.updateById(tCoursePackagePayment);
+
+
+        TCoursePackage tCoursePackage = tcpmapper.selectById(req.getCourseId());
+        // 添加课包
+        TCoursePackagePayment tCoursePackagePayment1 = new TCoursePackagePayment();
+        tCoursePackagePayment1.setAppUserId(userId);
+        Student student = studentClient.queryDefaultStudent(userId);
+        // student ID
+        Integer sId=null;
+        if(student!=null){
+            tCoursePackagePayment1.setStudentId(student.getId());
+            sId=student.getId();
+        }
+        tCoursePackagePayment1.setCoursePackageId(tCoursePackage.getId());
+        tCoursePackagePayment1.setPayType(7);
+        tCoursePackagePayment1.setClassHours(req.getNum());
+        tCoursePackagePayment1.setOriginalPrice(0.0);
+        tCoursePackagePayment1.setTotalClassHours(req.getNum());
+        tCoursePackagePayment1.setLaveClassHours(req.getNum());
+        tCoursePackagePayment1.setAbsencesNumber(0);
+        tCoursePackagePayment1.setPayUserType(1);
+        tCoursePackagePayment1.setPayStatus(2);
+        tCoursePackagePayment1.setPayUserId(userId);
+        tCoursePackagePayment1.setStatus(1);
+        tCoursePackagePayment1.setState(1);
+        tCoursePackagePayment1.setInsertTime(new Date());
+        this.baseMapper.insert(tCoursePackagePayment1);
+        // 找出课包时间段
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+        String classStartTime = tCoursePackage.getClassStartTime();
+        String classEndTime = tCoursePackage.getClassEndTime();
+        String[] split = classStartTime.split(",");
+        String[] split1 = classEndTime.split(",");
+        List<String> time = req.getTime();
+        for (String s : time) {
+            for (int i = 0; i < split.length; i++) {
+                CoursePackageScheduling coursePackageScheduling = new CoursePackageScheduling();
+                coursePackageScheduling.setCourseId(tCoursePackage.getId());
+                try {
+                    Date parse = format.parse(s + " " + split[i]);
+                    Date parse1 = format.parse(s + " " + split1[i]);
+                    coursePackageScheduling.setClassDate(parse);
+                    coursePackageScheduling.setEndDate(parse1);
+                    coursePackageScheduling.setStatus(1);
+                    coursePackageSchedulingService.save(coursePackageScheduling);
+
+                    CoursePackageStudent student1 = new CoursePackageStudent();
+                    student1.setAppUserId(userId);
+                    student1.setStudentId(sId);
+                    student1.setCoursePackageId(tCoursePackage.getId());
+                    student1.setCoursePackagePaymentId(tCoursePackagePayment1.getId());
+                    student1.setCoursePackageSchedulingId(coursePackageScheduling.getId());
+                    student1.setSignInOrNot(0);
+                    student1.setReservationStatus(1);
+                    student1.setInsertTime(new Date());
+                    cpsMapper.insert(student1);
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                }
+
+            }
+        }
+
+
+        // 2.0
+        TCourseInfoRecord tCourseInfoRecord = new TCourseInfoRecord();
+        tCourseInfoRecord.setUserId(userId);
+        tCourseInfoRecord.setCourseId(req.getOldCourseId());
+        tCourseInfoRecord.setName("体验购课");
+        tCourseInfoRecord.setNum(req.getNum());
+        tCourseInfoRecord.setTime(new Date());
+        tCourseInfoRecord.setType(2);
+        appuClient.addCourseInfoRecord(tCourseInfoRecord);
+
+
+        if(tCoursePackagePayment.getLaveClassHours()<=3){
+            Integer appUserId = userId;
+
+            //调用推送
+            HttpHeaders headers = new HttpHeaders();
+            // 以表单的方式提交
+            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+            String s1 = appUserId + "_" + "Three";
+            //定时修改排课状态
+            String s = internalRestTemplate.getForObject("http://mb-cloud-gateway/netty/sendMsgToClient?id="+s1, String.class);
+            JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
+            if(jsonObject1.getIntValue("code") != 200){
+                System.err.println(jsonObject1.getString("msg"));
+            }
+        }
+
+        return ResultUtil.success();
+
+    }
+
+
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java
index 8111282..717e7c5 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/service/impl/TCoursePackageServiceImpl.java
@@ -1,5 +1,6 @@
 package com.dsh.course.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -12,24 +13,29 @@
 import com.dsh.course.feignclient.account.StudentClient;
 import com.dsh.course.feignclient.account.model.AppUser;
 import com.dsh.course.feignclient.account.model.Student;
+import com.dsh.course.feignclient.account.model.TCourseInfoRecord;
 import com.dsh.course.feignclient.activity.CouponClient;
 import com.dsh.course.feignclient.activity.UserCouponClient;
 import com.dsh.course.feignclient.activity.model.Coupon;
+import com.dsh.course.feignclient.activity.model.SendCouponReq;
 import com.dsh.course.feignclient.activity.model.UserCoupon;
 import com.dsh.course.feignclient.other.StoreClient;
 import com.dsh.course.feignclient.other.model.Store;
+import com.dsh.course.mapper.CoursePackageStudentMapper;
 import com.dsh.course.mapper.TCoursePackageMapper;
 import com.dsh.course.feignclient.model.CourseOfStoreVo;
 import com.dsh.course.model.*;
 import com.dsh.course.service.*;
 import com.dsh.course.util.*;
 import com.dsh.course.util.httpClinet.HttpResult;
+import org.omg.CORBA.INTERNAL;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -80,7 +86,8 @@
 
     @Autowired
     private CoursePackageStudentService coursePackageStudentService;
-
+    @Resource
+    private CoursePackageStudentMapper cpsMapper;
 
 
 
@@ -133,13 +140,214 @@
             coursePackageListVo.setName(coursePackage.getName());
             coursePackageListVo.setStoreName(null != store ? store.getName() : "");
             coursePackageListVo.setCoverDrawing(coursePackage.getCoverDrawing());
-            coursePackageListVo.setClassStartTime(coursePackage.getClassStartTime() + "-" + coursePackage.getClassEndTime());
+
+            // 2.0修改
+            String classStartTime = coursePackage.getClassStartTime();
+            String classEndTime = coursePackage.getClassEndTime();
+            ArrayList<String> classTime = new ArrayList<>();
+            String[] split = classStartTime.split(",");
+            String[] split3 = classEndTime.split(",");
+            for (int i = 0; i < split.length; i++) {
+                String s = split[i] + "-" +  split3[i];
+                classTime.add(s);
+            }
+            coursePackageListVo.setClassStartTime(classTime);
+            coursePackageListVo.setType(coursePackage.getType());
+
+
+
             coursePackageListVo.setApplicantsNumber(integer);
             coursePackageListVo.setPayType(coursePackage.getPayType());
             coursePackageListVo.setPlayPaiCoin(coursePackagePaymentConfig.getPlayPaiCoin());
 
             //会员显示原价和会员价(最低)。非会员显示会员价和支付价(最低)
             if(appUser.getIsVip() == 0){//非会员
+                List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                        .eq("type", 1).eq("auditStatus", 2));
+                Double vipPrice = coursePackagePaymentConfig.getCashPayment();
+                for (TCoursePackageDiscount coursePackageDiscount : list2) {
+                    Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
+                    if(vipPrice.compareTo(num1) > 0){
+                        vipPrice = num1;
+                    }
+                }
+                coursePackageListVo.setVipPrice(vipPrice);
+
+                Double paymentPrice = coursePackagePaymentConfig.getCashPayment();
+                List<TCoursePackageDiscount> list3 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                        .eq("type", 3).eq("auditStatus", 2));
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                for (TCoursePackageDiscount coursePackageDiscount : list3) {
+                    /**
+                     * [{
+                     * 	"startDate": "2023-01-01 00:00:00",
+                     * 	"endDate": "2023-12-31 23:59:59",
+                     * 	"startTime": "02:00:00",
+                     * 	"endTime": "23:00:00",
+                     * 	"weeks": [1, 2, 7],
+                     * 	"cashPayment": 100
+                     * }]
+                     */
+                    JSONArray jsonArray = JSON.parseArray(coursePackageDiscount.getContent());
+                    for (int i = 0; i < jsonArray.size(); i++) {
+                        try {
+                            JSONObject jsonObject = jsonArray.getJSONObject(i);
+                            String startDate = jsonObject.getString("startDate");
+                            String endDate = jsonObject.getString("endDate");
+                            String startTime = jsonObject.getString("startTime");
+                            String endTime = jsonObject.getString("endTime");
+                            List<Integer> weeks = jsonObject.getJSONArray("weeks").toJavaList(Integer.class);
+                            Double cashPayment = jsonObject.getDouble("cashPayment");
+                            Date startDate_date = sdf.parse(startDate);
+                            Date endDate_date = sdf.parse(endDate);
+                            long timeMillis = System.currentTimeMillis();
+                            if(timeMillis >= startDate_date.getTime() && timeMillis < endDate_date.getTime()){
+                                Date date = new Date();
+                                Calendar calendar = Calendar.getInstance();
+                                calendar.setTime(date);
+                                int week = calendar.get(Calendar.DAY_OF_WEEK);
+                                boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);
+                                if(isFirstSunday){
+                                    week = week - 1;
+                                    if(week == 0){
+                                        week = 7;
+                                    }
+                                }
+                                if(!weeks.contains(week)){
+                                    continue;
+                                }
+
+                                String[] split1 = startTime.split(":");
+                                Integer hour1 = Integer.valueOf(split1[0]);
+                                Calendar s = Calendar.getInstance();
+                                s.setTime(date);
+                                s.set(Calendar.HOUR_OF_DAY, hour1);
+                                s.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
+                                s.set(Calendar.SECOND, Integer.valueOf(split1[2]));
+
+                                String[] split2 = endTime.split(":");
+                                Integer hour2 = Integer.valueOf(split2[0]);
+                                Calendar e = Calendar.getInstance();
+                                e.setTime(date);
+                                e.set(Calendar.HOUR_OF_DAY, hour2);
+                                e.set(Calendar.MINUTE, Integer.valueOf(split2[1]));
+                                e.set(Calendar.SECOND, Integer.valueOf(split2[2]));
+
+                                if(hour1 > hour2){
+                                    if(s.getTimeInMillis() > date.getTime()){
+                                        s.set(Calendar.DAY_OF_YEAR, s.get(Calendar.DAY_OF_YEAR) - 1);
+                                    }else{
+                                        e.set(Calendar.DAY_OF_YEAR, e.get(Calendar.DAY_OF_YEAR) + 1);
+                                    }
+                                }
+                                if(timeMillis >= s.getTimeInMillis() && timeMillis < e.getTimeInMillis() && paymentPrice.compareTo(cashPayment) > 0){
+                                    paymentPrice = cashPayment;
+                                }
+                            }
+                        }catch (Exception e){
+                            e.printStackTrace();
+                        }
+                    }
+                }
+                coursePackageListVo.setPaymentPrice(paymentPrice);
+            }else{
+                List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                        .eq("type", 1).eq("auditStatus", 2));
+                Double vipPrice = coursePackagePaymentConfig.getCashPayment();
+                for (TCoursePackageDiscount coursePackageDiscount : list2) {
+                    Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
+                    if(vipPrice.compareTo(num1) > 0){
+                        vipPrice = num1;
+                    }
+                }
+                coursePackageListVo.setPaymentPrice(vipPrice);
+                coursePackageListVo.setOriginalPrice(coursePackagePaymentConfig.getCashPayment());
+            }
+
+            Map<String, Double> distance = GeodesyUtil.getDistance(coursePackageList.getLon() + "," + coursePackageList.getLat(), store.getLon() + "," + store.getLat());
+            coursePackageListVo.setDistance(distance.get("WGS84") / 1000);
+            listVos.add(coursePackageListVo);
+        }
+
+        //销量排行
+        if(ToolUtil.isNotEmpty(coursePackageList.getSalesRanking())){
+            Collections.sort(listVos, new Comparator<CoursePackageListVo>() {
+                public int compare(CoursePackageListVo s1, CoursePackageListVo s2) {
+                    return Integer.compare(s1.getApplicantsNumber(), s2.getApplicantsNumber());
+                }
+            });
+        }
+        //距离排行
+        if(ToolUtil.isNotEmpty(coursePackageList.getDistanceSort())){
+            Collections.sort(listVos, new Comparator<CoursePackageListVo>() {
+                public int compare(CoursePackageListVo s1, CoursePackageListVo s2) {
+                    return Double.compare(s1.getDistance(), s2.getDistance());
+                }
+            });
+        }
+        return listVos;
+    }
+
+
+    @Override
+    public List<CoursePackageListVo> queryCourseListOne(CoursePackageList coursePackageList) throws Exception {
+//        AppUser appUser = appUserClient.queryAppUser(uid);
+        Map<String, String> geocode = gdMapGeocodingUtil.geocode(coursePackageList.getLon(), coursePackageList.getLat());
+        String provinceCode = geocode.get("provinceCode");
+        String cityCode = geocode.get("cityCode");
+        QueryWrapper<TCoursePackage> wrapper = new QueryWrapper<TCoursePackage>().in("status", Arrays.asList(1, 2))
+                .eq("auditStatus", 2).eq("state", 1).eq("provinceCode", provinceCode).eq("cityCode", cityCode);
+        if(null != coursePackageList.getCoursePackageTypeId()){
+            wrapper.eq("coursePackageTypeId", coursePackageList.getCoursePackageTypeId());
+        }
+        if(null != coursePackageList.getStoreId()){
+            wrapper.eq("storeId", coursePackageList.getStoreId());
+        }
+        if(null != coursePackageList.getStoreId()){
+            wrapper.eq("storeId", coursePackageList.getStoreId());
+        }
+        if(ToolUtil.isNotEmpty(coursePackageList.getSearch())){
+            wrapper.like("name", coursePackageList.getSearch());
+            List<Store> stores = storeClient.queryStoreListByName(coursePackageList.getSearch());
+            List<Integer> collect = stores.stream().map(Store::getId).collect(Collectors.toList());
+            if(collect.size() > 0){
+                wrapper.or().in("storeId", collect);
+            }
+        }
+        List<TCoursePackage> list = this.list(wrapper.last(" order by sort, insertTime desc"));
+        List<CoursePackageListVo> listVos = new ArrayList<>();
+        for (TCoursePackage coursePackage : list) {
+            Store store = storeClient.queryStoreById(coursePackage.getStoreId());
+            Integer integer = coursePackagePaymentService.queryCountNumber(coursePackage.getId());
+            CoursePackagePaymentConfig coursePackagePaymentConfig = coursePackagePaymentConfigService.getOne(new QueryWrapper<CoursePackagePaymentConfig>()
+                    .eq("coursePackageId", coursePackage.getId()).orderByAsc("classHours").last(" limit 0, 1"));
+            CoursePackageListVo coursePackageListVo = new CoursePackageListVo();
+            coursePackageListVo.setId(coursePackage.getId());
+            coursePackageListVo.setName(coursePackage.getName());
+            coursePackageListVo.setStoreName(null != store ? store.getName() : "");
+            coursePackageListVo.setCoverDrawing(coursePackage.getCoverDrawing());
+
+            // 2.0修改
+            String classStartTime = coursePackage.getClassStartTime();
+            String classEndTime = coursePackage.getClassEndTime();
+            ArrayList<String> classTime = new ArrayList<>();
+            String[] split = classStartTime.split(",");
+            String[] split3 = classEndTime.split(",");
+            for (int i = 0; i < split.length; i++) {
+                String s = split[i] + "-" +  split3[i];
+                classTime.add(s);
+            }
+            coursePackageListVo.setClassStartTime(classTime);
+            coursePackageListVo.setType(coursePackage.getType());
+
+
+
+            coursePackageListVo.setApplicantsNumber(integer);
+            coursePackageListVo.setPayType(coursePackage.getPayType());
+            coursePackageListVo.setPlayPaiCoin(coursePackagePaymentConfig.getPlayPaiCoin());
+
+            //会员显示原价和会员价(最低)。非会员显示会员价和支付价(最低)
+            if(false){//非会员
                 List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
                         .eq("type", 1).eq("auditStatus", 2));
                 Double vipPrice = coursePackagePaymentConfig.getCashPayment();
@@ -276,155 +484,168 @@
      */
     @Override
     public CoursePackageInfo queryCourseInfo(Integer uid, Integer id, String lon, String lat) throws Exception {
-        AppUser appUser = appUserClient.queryAppUser(uid);
-        TCoursePackage coursePackage = this.getById(id);
-        CoursePackageInfo coursePackageInfo = new CoursePackageInfo();
-        coursePackageInfo.setId(id);
-        coursePackageInfo.setCoverDrawing(coursePackage.getCoverDrawing());
-        coursePackageInfo.setName(coursePackage.getName());
-        Store store = storeClient.queryStoreById(coursePackage.getStoreId());
-        coursePackageInfo.setStoreName(store.getName());
-        coursePackageInfo.setStoreCoverDrawing(store.getCoverDrawing());
-        coursePackageInfo.setStoreAddress(store.getAddress());
-        coursePackageInfo.setLon(store.getLon());
-        coursePackageInfo.setLat(store.getLat());
-        if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){
-            Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
-            double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
-            coursePackageInfo.setDistance(wgs84);
-        }
+            AppUser appUser = appUserClient.queryAppUser(uid);
+            TCoursePackage coursePackage = this.getById(id);
+            CoursePackageInfo coursePackageInfo = new CoursePackageInfo();
+            coursePackageInfo.setId(id);
+            coursePackageInfo.setCoverDrawing(coursePackage.getCoverDrawing());
+            coursePackageInfo.setName(coursePackage.getName());
+            Store store = storeClient.queryStoreById(coursePackage.getStoreId());
+            coursePackageInfo.setStoreName(store.getName());
+            coursePackageInfo.setStoreCoverDrawing(store.getCoverDrawing());
+            coursePackageInfo.setStoreAddress(store.getAddress());
+            coursePackageInfo.setLon(store.getLon());
+            coursePackageInfo.setLat(store.getLat());
+            if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){
+                Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
+                double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
+                coursePackageInfo.setDistance(wgs84);
+            }
 
-        String[] split = coursePackage.getClassWeeks().split(";");
-        coursePackageInfo.setWeeks(Arrays.asList(split));
-        coursePackageInfo.setTimes(coursePackage.getClassStartTime() + "-" + coursePackage.getClassEndTime());
-        coursePackageInfo.setDetailDrawing(coursePackage.getDetailDrawing());
-        coursePackageInfo.setIntroduceDrawing(coursePackage.getIntroduceDrawing());
-        List<CoursePackagePaymentConfigVo> list = new ArrayList<>();
-        List<CoursePackagePaymentConfig> list1 = coursePackagePaymentConfigService.list(new QueryWrapper<CoursePackagePaymentConfig>().eq("coursePackageId", id).orderByAsc("classHours"));
-        list1.forEach(coursePackagePaymentConfig -> {
-            CoursePackagePaymentConfigVo coursePackagePaymentConfigVo = new CoursePackagePaymentConfigVo();
-            coursePackagePaymentConfigVo.setId(coursePackagePaymentConfig.getId());
-            coursePackagePaymentConfigVo.setClassHours(coursePackagePaymentConfig.getClassHours());
-            coursePackagePaymentConfigVo.setPayType(coursePackage.getPayType());
-            coursePackagePaymentConfigVo.setPlayPaiCoin(coursePackagePaymentConfig.getPlayPaiCoin());
-            //会员显示原价和支付价(会员价)。非会员显示会员价和支付价(最低)
-            if(appUser.getIsVip() == 0){//非会员
-                List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
-                        .eq("type", 1).eq("auditStatus", 2));
-                Double vipPrice = coursePackagePaymentConfig.getCashPayment();
-                for (TCoursePackageDiscount coursePackageDiscount : list2) {
-                    Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
-                    if(vipPrice.compareTo(num1) > 0){
-                        vipPrice = num1;
-                    }
-                }
-                coursePackagePaymentConfigVo.setVipPrice(vipPrice);
+            String[] split = coursePackage.getClassWeeks().split(";");
+            coursePackageInfo.setWeeks(Arrays.asList(split));
 
-                Double paymentPrice = coursePackagePaymentConfig.getCashPayment();
-                List<TCoursePackageDiscount> list3 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
-                        .eq("type", 3).eq("auditStatus", 2));
-                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
-                for (TCoursePackageDiscount coursePackageDiscount : list3) {
-                    /**
-                     * [{
-                     * 	"startDate": "2023-01-01 00:00:00",
-                     * 	"endDate": "2023-12-31 23:59:59",
-                     * 	"startTime": "02:00:00",
-                     * 	"endTime": "23:00:00",
-                     * 	"weeks": [1, 2, 7],
-                     * 	"cashPayment": 100
-                     * }]
-                     */
-                    JSONArray jsonArray = JSON.parseArray(coursePackageDiscount.getContent());
-                    for (int i = 0; i < jsonArray.size(); i++) {
-                        try {
-                            JSONObject jsonObject = jsonArray.getJSONObject(i);
-                            String startDate = jsonObject.getString("startDate");
-                            String endDate = jsonObject.getString("endDate");
-                            String startTime = jsonObject.getString("startTime");
-                            String endTime = jsonObject.getString("endTime");
-                            List<Integer> weeks = jsonObject.getJSONArray("weeks").toJavaList(Integer.class);
-                            Double cashPayment = jsonObject.getDouble("cashPayment");
-                            Date startDate_date = sdf.parse(startDate);
-                            Date endDate_date = sdf.parse(endDate);
-                            long timeMillis = System.currentTimeMillis();
-                            if(timeMillis >= startDate_date.getTime() && timeMillis < endDate_date.getTime()){
-                                Date date = new Date();
-                                Calendar calendar = Calendar.getInstance();
-                                calendar.setTime(date);
-                                int week = calendar.get(Calendar.DAY_OF_WEEK);
-                                boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);
-                                if(isFirstSunday){
-                                    week = week - 1;
-                                    if(week == 0){
-                                        week = 7;
-                                    }
-                                }
-                                if(!weeks.contains(week)){
-                                    continue;
-                                }
+            // 2.0
+            String classStartTime = coursePackage.getClassStartTime();
+            String classEndTime = coursePackage.getClassEndTime();
+            ArrayList<String> classTime = new ArrayList<>();
+            String[] split4 = classStartTime.split(",");
+            String[] split3 = classEndTime.split(",");
+            for (int i = 0; i < split4.length; i++) {
+                String s = split4[i] + "-" +  split3[i];
+                classTime.add(s);
+            }
+            coursePackageInfo.setTimes(classTime);
+            coursePackageInfo.setType(coursePackage.getType());
 
-                                String[] split1 = startTime.split(":");
-                                Integer hour1 = Integer.valueOf(split1[0]);
-                                Calendar s = Calendar.getInstance();
-                                s.setTime(date);
-                                s.set(Calendar.HOUR_OF_DAY, hour1);
-                                s.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
-                                s.set(Calendar.SECOND, Integer.valueOf(split1[2]));
-
-                                String[] split2 = endTime.split(":");
-                                Integer hour2 = Integer.valueOf(split2[0]);
-                                Calendar e = Calendar.getInstance();
-                                e.setTime(date);
-                                e.set(Calendar.HOUR_OF_DAY, hour2);
-                                e.set(Calendar.MINUTE, Integer.valueOf(split2[1]));
-                                e.set(Calendar.SECOND, Integer.valueOf(split2[2]));
-
-                                if(hour1 > hour2){
-                                    if(s.getTimeInMillis() > date.getTime()){
-                                        s.set(Calendar.DAY_OF_YEAR, s.get(Calendar.DAY_OF_YEAR) - 1);
-                                    }else{
-                                        e.set(Calendar.DAY_OF_YEAR, e.get(Calendar.DAY_OF_YEAR) + 1);
-                                    }
-                                }
-                                if(timeMillis >= s.getTimeInMillis() && timeMillis < e.getTimeInMillis() && paymentPrice.compareTo(cashPayment) > 0){
-                                    paymentPrice = cashPayment;
-                                }
-                            }
-                        }catch (Exception e){
-                            e.printStackTrace();
+            coursePackageInfo.setDetailDrawing(coursePackage.getDetailDrawing());
+            coursePackageInfo.setIntroduceDrawing(coursePackage.getIntroduceDrawing());
+            List<CoursePackagePaymentConfigVo> list = new ArrayList<>();
+            List<CoursePackagePaymentConfig> list1 = coursePackagePaymentConfigService.list(new QueryWrapper<CoursePackagePaymentConfig>().eq("coursePackageId", id).orderByAsc("classHours"));
+            list1.forEach(coursePackagePaymentConfig -> {
+                CoursePackagePaymentConfigVo coursePackagePaymentConfigVo = new CoursePackagePaymentConfigVo();
+                coursePackagePaymentConfigVo.setId(coursePackagePaymentConfig.getId());
+                coursePackagePaymentConfigVo.setClassHours(coursePackagePaymentConfig.getClassHours());
+                coursePackagePaymentConfigVo.setPayType(coursePackage.getPayType());
+                coursePackagePaymentConfigVo.setPlayPaiCoin(coursePackagePaymentConfig.getPlayPaiCoin());
+                //会员显示原价和支付价(会员价)。非会员显示会员价和支付价(最低)
+                if(appUser.getIsVip() == 0){//非会员
+                    List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                            .eq("type", 1).eq("auditStatus", 2));
+                    Double vipPrice = coursePackagePaymentConfig.getCashPayment();
+                    for (TCoursePackageDiscount coursePackageDiscount : list2) {
+                        Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
+                        if(vipPrice.compareTo(num1) > 0){
+                            vipPrice = num1;
                         }
                     }
-                }
-                coursePackagePaymentConfigVo.setPaymentPrice(paymentPrice);
-            }else{
-                List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
-                        .eq("type", 1).eq("auditStatus", 2));
-                Double vipPrice = coursePackagePaymentConfig.getCashPayment();
-                for (TCoursePackageDiscount coursePackageDiscount : list2) {
-                    Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
-                    if(vipPrice.compareTo(num1) > 0){
-                        vipPrice = num1;
-                    }
-                }
-                coursePackagePaymentConfigVo.setPaymentPrice(vipPrice);
-                coursePackagePaymentConfigVo.setOriginalPrice(coursePackagePaymentConfig.getCashPayment());
-            }
-            list.add(coursePackagePaymentConfigVo);
-        });
-        coursePackageInfo.setList(list);
+                    coursePackagePaymentConfigVo.setVipPrice(vipPrice);
 
-        Student student = studentClient.queryDefaultStudent(uid);
-        StudentVo studentVo = new StudentVo();
-        if(null != student){
-            studentVo.setId(student.getId());
-            studentVo.setPhone(student.getPhone());
-            studentVo.setName(student.getName());
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
-            studentVo.setAge(Integer.valueOf(sdf.format(new Date())) - Integer.valueOf(sdf.format(student.getBirthday())));
-        }
-        coursePackageInfo.setStudent(studentVo);
-        return coursePackageInfo;
+                    Double paymentPrice = coursePackagePaymentConfig.getCashPayment();
+                    List<TCoursePackageDiscount> list3 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                            .eq("type", 3).eq("auditStatus", 2));
+                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+                    for (TCoursePackageDiscount coursePackageDiscount : list3) {
+                        /**
+                         * [{
+                         * 	"startDate": "2023-01-01 00:00:00",
+                         * 	"endDate": "2023-12-31 23:59:59",
+                         * 	"startTime": "02:00:00",
+                         * 	"endTime": "23:00:00",
+                         * 	"weeks": [1, 2, 7],
+                         * 	"cashPayment": 100
+                         * }]
+                         */
+                        JSONArray jsonArray = JSON.parseArray(coursePackageDiscount.getContent());
+                        for (int i = 0; i < jsonArray.size(); i++) {
+                            try {
+                                JSONObject jsonObject = jsonArray.getJSONObject(i);
+                                String startDate = jsonObject.getString("startDate");
+                                String endDate = jsonObject.getString("endDate");
+                                String startTime = jsonObject.getString("startTime");
+                                String endTime = jsonObject.getString("endTime");
+                                List<Integer> weeks = jsonObject.getJSONArray("weeks").toJavaList(Integer.class);
+                                Double cashPayment = jsonObject.getDouble("cashPayment");
+                                Date startDate_date = sdf.parse(startDate);
+                                Date endDate_date = sdf.parse(endDate);
+                                long timeMillis = System.currentTimeMillis();
+                                if(timeMillis >= startDate_date.getTime() && timeMillis < endDate_date.getTime()){
+                                    Date date = new Date();
+                                    Calendar calendar = Calendar.getInstance();
+                                    calendar.setTime(date);
+                                    int week = calendar.get(Calendar.DAY_OF_WEEK);
+                                    boolean isFirstSunday = (calendar.getFirstDayOfWeek() == Calendar.SUNDAY);
+                                    if(isFirstSunday){
+                                        week = week - 1;
+                                        if(week == 0){
+                                            week = 7;
+                                        }
+                                    }
+                                    if(!weeks.contains(week)){
+                                        continue;
+                                    }
+
+                                    String[] split1 = startTime.split(":");
+                                    Integer hour1 = Integer.valueOf(split1[0]);
+                                    Calendar s = Calendar.getInstance();
+                                    s.setTime(date);
+                                    s.set(Calendar.HOUR_OF_DAY, hour1);
+                                    s.set(Calendar.MINUTE, Integer.valueOf(split1[1]));
+                                    s.set(Calendar.SECOND, Integer.valueOf(split1[2]));
+
+                                    String[] split2 = endTime.split(":");
+                                    Integer hour2 = Integer.valueOf(split2[0]);
+                                    Calendar e = Calendar.getInstance();
+                                    e.setTime(date);
+                                    e.set(Calendar.HOUR_OF_DAY, hour2);
+                                    e.set(Calendar.MINUTE, Integer.valueOf(split2[1]));
+                                    e.set(Calendar.SECOND, Integer.valueOf(split2[2]));
+
+                                    if(hour1 > hour2){
+                                        if(s.getTimeInMillis() > date.getTime()){
+                                            s.set(Calendar.DAY_OF_YEAR, s.get(Calendar.DAY_OF_YEAR) - 1);
+                                        }else{
+                                            e.set(Calendar.DAY_OF_YEAR, e.get(Calendar.DAY_OF_YEAR) + 1);
+                                        }
+                                    }
+                                    if(timeMillis >= s.getTimeInMillis() && timeMillis < e.getTimeInMillis() && paymentPrice.compareTo(cashPayment) > 0){
+                                        paymentPrice = cashPayment;
+                                    }
+                                }
+                            }catch (Exception e){
+                                e.printStackTrace();
+                            }
+                        }
+                    }
+                    coursePackagePaymentConfigVo.setPaymentPrice(paymentPrice);
+                }else{
+                    List<TCoursePackageDiscount> list2 = coursePackageDiscountService.list(new QueryWrapper<TCoursePackageDiscount>().eq("coursePackagePaymentConfigId", coursePackagePaymentConfig.getId())
+                            .eq("type", 1).eq("auditStatus", 2));
+                    Double vipPrice = coursePackagePaymentConfig.getCashPayment();
+                    for (TCoursePackageDiscount coursePackageDiscount : list2) {
+                        Double num1 = JSON.parseObject(coursePackageDiscount.getContent()).getDouble("discountMember");
+                        if(vipPrice.compareTo(num1) > 0){
+                            vipPrice = num1;
+                        }
+                    }
+                    coursePackagePaymentConfigVo.setPaymentPrice(vipPrice);
+                    coursePackagePaymentConfigVo.setOriginalPrice(coursePackagePaymentConfig.getCashPayment());
+                }
+                list.add(coursePackagePaymentConfigVo);
+            });
+            coursePackageInfo.setList(list);
+
+            Student student = studentClient.queryDefaultStudent(uid);
+            StudentVo studentVo = new StudentVo();
+            if(null != student){
+                studentVo.setId(student.getId());
+                studentVo.setPhone(student.getPhone());
+                studentVo.setName(student.getName());
+                SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
+                studentVo.setAge(Integer.valueOf(sdf.format(new Date())) - Integer.valueOf(sdf.format(student.getBirthday())));
+            }
+            coursePackageInfo.setStudent(studentVo);
+            return coursePackageInfo;
     }
 
 
@@ -511,6 +732,8 @@
             }
             return playPaiCoinPaymentCourse(appUser, price, paymentCourseVo);
         }
+
+
         return ResultUtil.success();
     }
 
@@ -551,8 +774,14 @@
             coursePackagePaymentService.save(coursePackagePayment);
         }
 
+        Student student = studentClient.queryDefaultStudent(uid);
+        Integer sid=null;
+        if(student!=null){
+            sid=student.getId();
+        }
         ResultUtil weixinpay = payMoneyUtil.weixinpay("购买课程", "", code, paymentPrice.toString(), "/base/course/weChatPaymentCourseCallback", "APP", "");
         if(weixinpay.getCode() == 200){
+            Integer finalSid = sid;
             new Thread(new Runnable() {
                 @Override
                 public void run() {
@@ -595,6 +824,10 @@
                                         coursePackagePayment.setOrderNumber(transaction_id);
                                     }
                                     coursePackagePaymentService.updateBatchById(list);
+                                    // 2.0
+                                    userCouponClient.sendUserCoupon(new SendCouponReq(uid,coursePackagePaymentConfig.getCouponIds()));
+
+                                    addPackageStudent(paymentCourseVo.getId(),uid, finalSid,one.getId());
                                     break;
                                 }
                                 if("USERPAYING".equals(s)){
@@ -648,8 +881,15 @@
             coursePackagePaymentService.save(coursePackagePayment);
         }
 
+        Student student = studentClient.queryDefaultStudent(uid);
+        Integer sid=null;
+        if(student!=null){
+            sid=student.getId();
+        }
+
         ResultUtil alipay = payMoneyUtil.alipay("购买课程", "购买课程", "", code, paymentPrice.toString(), "/base/course/aliPaymentCourseCallback");
         if(alipay.getCode() == 200){
+            Integer finalSid = sid;
             new Thread(new Runnable() {
                 @Override
                 public void run() {
@@ -689,6 +929,16 @@
                                         coursePackagePayment.setOrderNumber(tradeNo);
                                     }
                                     coursePackagePaymentService.updateBatchById(list);
+
+                                    // 2.0
+                                    userCouponClient.sendUserCoupon(new SendCouponReq(uid,coursePackagePaymentConfig.getCouponIds()));
+
+
+
+                                    if(student!=null){
+
+                                    }
+                                    addPackageStudent(paymentCourseVo.getId(),uid, finalSid,one.getId());
                                     break;
                                 }
                                 if("WAIT_BUYER_PAY".equals(s)){
@@ -739,12 +989,181 @@
             coursePackagePayment.setState(1);
             coursePackagePayment.setInsertTime(new Date());
             coursePackagePaymentService.save(coursePackagePayment);
+            Integer sId=null;
+            Student student = studentClient.queryDefaultStudent(appUser.getId());
+            if(student!=null){
+                sId=student.getId();
+            }
+            addPackageStudent(paymentCourseVo.getId(),appUser.getId(),sId,coursePackagePayment.getId());
         }
 
         Integer playPaiCoins = appUser.getPlayPaiCoins();
         appUser.setPlayPaiCoins(playPaiCoins - paymentPrice.intValue());
         appUserClient.updateAppUser(appUser);
+
+        // 2.0
+        String couponIds = coursePackagePaymentConfig.getCouponIds();
+        if(ToolUtil.isNotEmpty(couponIds)){
+            // 赠送优惠券
+            userCouponClient.sendUserCoupon(new SendCouponReq(appUser.getId(),couponIds));
+        }
         return ResultUtil.success();
+    }
+
+
+    private void addPackageStudent(Integer courseId, Integer userId, Integer sId,Long paymentId){
+        // 课包
+        TCoursePackage tCoursePackage = this.baseMapper.selectById(courseId);
+
+
+
+        String classWeeks = tCoursePackage.getClassWeeks();
+        List<Integer> week = week(classWeeks);
+
+        String[] split = tCoursePackage.getClassStartTime().split(",");
+        String[] split1 = tCoursePackage.getClassEndTime().split(",");
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+        SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+        // 本周周几
+        int i = DateUtil.dayOfWeek(new Date())-1;
+        for (Integer integer : week) {
+            if(integer<i){
+                // 找下一周的时间
+                Calendar instance = Calendar.getInstance();
+                instance.add(Calendar.DATE,7-(i-integer));
+                Date time = instance.getTime();
+
+                for (int i1 = 0; i1 < split.length; i1++) {
+
+                    CoursePackageScheduling coursePackageScheduling = new CoursePackageScheduling();
+                    coursePackageScheduling.setCourseId(tCoursePackage.getId());
+                    try {
+                        Date parse = format1.parse(format.format(time) + " " + split[i1]);
+                        Date parse1 = format1.parse(format.format(time) + " " + split1[i1]);
+                        coursePackageScheduling.setClassDate(parse);
+                        coursePackageScheduling.setEndDate(parse1);
+                        coursePackageScheduling.setStatus(1);
+                        coursePackageSchedulingService.save(coursePackageScheduling);
+
+                        CoursePackageStudent student1 = new CoursePackageStudent();
+                        student1.setAppUserId(userId);
+                        student1.setStudentId(sId);
+                        student1.setCoursePackageId(tCoursePackage.getId());
+                        student1.setCoursePackagePaymentId(paymentId);
+                        student1.setCoursePackageSchedulingId(coursePackageScheduling.getId());
+                        student1.setSignInOrNot(0);
+                        student1.setReservationStatus(1);
+                        student1.setInsertTime(new Date());
+                        cpsMapper.insert(student1);
+                    } catch (ParseException e) {
+                        e.printStackTrace();
+                    }
+
+                }
+
+            }else if(integer>i) {
+                Calendar instance = Calendar.getInstance();
+                instance.add(Calendar.DATE,integer-i);
+                Date time = instance.getTime();
+
+                for (int i1 = 0; i1 < split.length; i1++) {
+                    CoursePackageScheduling coursePackageScheduling = new CoursePackageScheduling();
+                    coursePackageScheduling.setCourseId(tCoursePackage.getId());
+                    try {
+                        Date parse = format1.parse(format.format(time) + " " + split[i1]);
+                        Date parse1 = format1.parse(format.format(time) + " " + split1[i1]);
+                        coursePackageScheduling.setClassDate(parse);
+                        coursePackageScheduling.setEndDate(parse1);
+                        coursePackageScheduling.setStatus(1);
+                        coursePackageSchedulingService.save(coursePackageScheduling);
+
+                        CoursePackageStudent student1 = new CoursePackageStudent();
+                        student1.setAppUserId(userId);
+                        student1.setStudentId(sId);
+                        student1.setCoursePackageId(tCoursePackage.getId());
+                        student1.setCoursePackagePaymentId(paymentId);
+                        student1.setCoursePackageSchedulingId(coursePackageScheduling.getId());
+                        student1.setSignInOrNot(0);
+                        student1.setReservationStatus(1);
+                        student1.setInsertTime(new Date());
+                        cpsMapper.insert(student1);
+                    } catch (ParseException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }else {
+                Calendar instance = Calendar.getInstance();
+                instance.add(Calendar.DATE,7);
+                Date time = instance.getTime();
+
+                for (int i1 = 0; i1 < split.length; i1++) {
+                    CoursePackageScheduling coursePackageScheduling = new CoursePackageScheduling();
+                    coursePackageScheduling.setCourseId(tCoursePackage.getId());
+                    try {
+                        Date parse = format1.parse(format.format(time) + " " + split[i1]);
+                        Date parse1 = format1.parse(format.format(time) + " " + split1[i1]);
+                        coursePackageScheduling.setClassDate(parse);
+                        coursePackageScheduling.setEndDate(parse1);
+                        coursePackageScheduling.setStatus(1);
+                        coursePackageSchedulingService.save(coursePackageScheduling);
+
+                        CoursePackageStudent student1 = new CoursePackageStudent();
+                        student1.setAppUserId(userId);
+                        student1.setStudentId(sId);
+                        student1.setCoursePackageId(tCoursePackage.getId());
+                        student1.setCoursePackagePaymentId(paymentId);
+                        student1.setCoursePackageSchedulingId(coursePackageScheduling.getId());
+                        student1.setSignInOrNot(0);
+                        student1.setReservationStatus(1);
+                        student1.setInsertTime(new Date());
+                        cpsMapper.insert(student1);
+                    } catch (ParseException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+        // 2.0
+        TCourseInfoRecord tCourseInfoRecord = new TCourseInfoRecord();
+        tCourseInfoRecord.setUserId(userId);
+        tCourseInfoRecord.setCourseId(courseId);
+        tCourseInfoRecord.setName("报名假期班");
+        tCourseInfoRecord.setNum(tCoursePackage.getNeedNum());
+        tCourseInfoRecord.setTime(new Date());
+        tCourseInfoRecord.setType(2);
+        appUserClient.addCourseInfoRecord(tCourseInfoRecord);
+
+
+    }
+    private List<Integer> week(String week){
+        String[] split = week.split(";");
+        ArrayList<Integer> integers = new ArrayList<>();
+        for (String s : split) {
+                switch (s){
+                    case "周一":
+                        integers.add(1);
+                        break;
+                    case "周二":
+                        integers.add(2);
+                        break;
+                    case "周三":
+                        integers.add(3);
+                        break;
+                    case "周四":
+                        integers.add(4);
+                        break;
+                    case "周五":
+                        integers.add(5);
+                        break;
+                    case "周六":
+                        integers.add(6);
+                        break;
+                    case "周日":
+                        integers.add(7);
+                        break;
+            }
+        }
+        return integers;
     }
 
 
@@ -961,4 +1380,14 @@
     public String getHours(Integer coursePackageId) {
         return this.baseMapper.getHours(coursePackageId);
     }
+
+    @Override
+    public ResultUtil paymentCourseCouponList(Integer uid, Integer coursePackagePaymentConfigId) {
+        CoursePackagePaymentConfig coursePackagePaymentConfig = coursePackagePaymentConfigService.getById(coursePackagePaymentConfigId);
+        if(ToolUtil.isEmpty(coursePackagePaymentConfig.getCouponIds())){
+            coursePackagePaymentConfig.setCouponIds("-1");
+        }
+        List<Coupon> coupons = couponClient.getCoupons(coursePackagePaymentConfig.getCouponIds());
+        return ResultUtil.success(coupons);
+    }
 }
diff --git a/cloud-server-course/src/main/java/com/dsh/course/util/TaskUtil.java b/cloud-server-course/src/main/java/com/dsh/course/util/TaskUtil.java
index fb26c90..27a46f7 100644
--- a/cloud-server-course/src/main/java/com/dsh/course/util/TaskUtil.java
+++ b/cloud-server-course/src/main/java/com/dsh/course/util/TaskUtil.java
@@ -1,9 +1,26 @@
 package com.dsh.course.util;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.dsh.course.entity.CoursePackageScheduling;
+import com.dsh.course.entity.CoursePackageStudent;
+import com.dsh.course.entity.TCoursePackagePayment;
+import com.dsh.course.service.CoursePackageStudentService;
 import com.dsh.course.service.ICoursePackageSchedulingService;
+import com.dsh.course.service.TCoursePackagePaymentService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.text.SimpleDateFormat;
+import java.util.*;
 
 /**
  * @author zhibing.pu
@@ -15,6 +32,13 @@
     @Autowired
     private ICoursePackageSchedulingService coursePackageSchedulingService;
 
+    @Autowired
+    private CoursePackageStudentService coursePackageStudentService;
+
+
+    @Autowired
+    private RestTemplate internalRestTemplate;
+
     /**
      * 每隔一分钟去处理的定时任务
      */
@@ -27,6 +51,42 @@
             e.printStackTrace();
         }
     }
+    /**
+     * 每隔一分钟去处理的定时任务   预约课时
+     */
+    @Scheduled(cron = "0 0 18 * * ?")
+    public void pushOne(){
+        try {
+            Calendar instance = Calendar.getInstance();
+            instance.add(Calendar.DATE,1);
+            Date time = instance.getTime();
+            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
+            String format1 = format.format(time);
+            // 获取明天排课
+            List<CoursePackageScheduling> list = coursePackageSchedulingService.list(new LambdaQueryWrapper<CoursePackageScheduling>().like(CoursePackageScheduling::getClassDate, format1));
+            for (CoursePackageScheduling coursePackageScheduling : list) {
+                CoursePackageStudent one = coursePackageStudentService.getOne(new LambdaQueryWrapper<CoursePackageStudent>().eq(CoursePackageStudent::getCoursePackageSchedulingId, coursePackageScheduling.getId()));
+                if(one!=null && one.getReservationStatus()==1){
+                    Integer appUserId = one.getAppUserId();
+
+                    //调用推送
+                    HttpHeaders headers = new HttpHeaders();
+                    // 以表单的方式提交
+                    headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+                    String s1 = appUserId + "_" + "Class";
+                    //定时修改排课状态
+                    String s = internalRestTemplate.getForObject("http://mb-cloud-gateway/netty/sendMsgToClient?id="+s1, String.class);
+                    JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
+                    if(jsonObject1.getIntValue("code") != 200){
+                        System.err.println(jsonObject1.getString("msg"));
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
 
 
 
diff --git a/cloud-server-gateway/pom.xml b/cloud-server-gateway/pom.xml
index a7e6fe4..1d58e08 100644
--- a/cloud-server-gateway/pom.xml
+++ b/cloud-server-gateway/pom.xml
@@ -16,6 +16,14 @@
 
 
 	<dependencies>
+
+
+
+		<dependency>
+			<groupId>io.netty</groupId>
+			<artifactId>netty-all</artifactId>
+			<version>4.1.27.Final</version>
+		</dependency>
 		<dependency>
 			<groupId>cn.mb.cloud</groupId>
 			<artifactId>mb-cloud-common-gateway</artifactId>
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/controller/NettyController.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/controller/NettyController.java
new file mode 100644
index 0000000..f1d485b
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/controller/NettyController.java
@@ -0,0 +1,48 @@
+package cn.mb.cloud.gateway.controller;
+
+
+import cn.mb.cloud.gateway.auth.ResultUtil;
+import cn.mb.cloud.gateway.util.applets.NettyWebSocketController;
+import cn.mb.cloud.gateway.util.echo.NettyChannelMap;
+import cn.mb.cloud.gateway.util.echo.NettyServerController;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.netty.channel.ChannelHandlerContext;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/netty")
+public class NettyController {
+
+
+    /**   3.4.5.6
+     * 向客户端推送消息
+     * @param id
+     * @param msg
+     */
+    @ResponseBody
+    @GetMapping("/sendMsgToClient")
+    public String sendMsgToClient(String id, Integer type, String msg){
+        System.out.println(id+"|"+type+"|"+msg+"!!!!!!!!");
+        if(true){//用户端
+            String[] split = id.split("_");
+            ChannelHandlerContext channel = NettyChannelMap.getData("USER" + split[0]);
+            if(null != channel){
+                JSONObject jsonObject = new JSONObject();
+                jsonObject.put("code", 200);
+                jsonObject.put("msg", "SUCCESS");
+                jsonObject.put("method", "CLASS");
+                Map<String, Object> map = new HashMap<>();
+                jsonObject.put("data", map);
+                NettyServerController.sendMsgToClient(channel, jsonObject.toJSONString());
+                return JSON.toJSONString(ResultUtil.success());
+            }
+            return JSON.toJSONString(ResultUtil.error("推送失败-----用户id=" + id));
+
+        }
+        return JSON.toJSONString(ResultUtil.error("推送失败"));
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SinataUtil.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SinataUtil.java
new file mode 100644
index 0000000..1a17294
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SinataUtil.java
@@ -0,0 +1,405 @@
+package cn.mb.cloud.gateway.util;
+
+import java.io.UnsupportedEncodingException;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * 基本数据处理工具类
+ */
+public class SinataUtil {
+	/**
+	 * List集合分页<br/> 
+	 * 创建人:Mryang<br/>
+	 * 时间:2016年7月28日-下午2:58:14 <br/> 
+	 * @param <T>
+	 * @param pageNo
+	 * @param pageSize
+	 * @param list 
+	 * @throws Exception List<UserOrderList> <br/>
+	 */
+	public static <T> List<T> listpage(int pageNo, int pageSize, List<T> list) throws Exception {
+		List<T> result = new ArrayList<T>();
+		if (list != null && list.size() > 0) {
+			int allCount = list.size();
+			if(pageNo > 1 && allCount < pageSize) {
+				return new ArrayList<>();
+			}
+			int pageCount = (allCount + pageSize - 1) / pageSize;
+			if (pageNo >= pageCount) {
+				pageNo = pageCount;
+			}
+			int start = (pageNo - 1) * pageSize;
+			int end = pageNo * pageSize;
+			if (end >= allCount) {
+				end = allCount;
+			}
+			for (int i = start; i < end; i++) {
+				result.add(list.get(i));
+			}
+		}
+		return (result != null && result.size() > 0) ? result : new ArrayList<T>();
+	}
+
+	/**
+	 * Double类型取整
+	 * @param num
+	 * @return
+	 */
+	public static String doubleTrans(double num) {
+		return String.valueOf((long) num);
+	}
+
+	/**
+	 * Double类型保留1位小数
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleRetainOne(double num) {
+		DecimalFormat dfs = new DecimalFormat("0.0");
+		return dfs.format(num);
+	}
+
+	/**
+	 * Double类型保留2位小数
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleRetainTwo(double num) {
+		DecimalFormat dfs = new DecimalFormat("0.00");
+		String.format("%.2f", num);
+		return dfs.format(num);
+	}
+
+	/**
+	 * Double类型保留1位小数(四舍五入)
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleForwardOne(double num) {
+		return String.format("%.1f", num);
+	}
+
+	/**
+	 * Double类型保留2位小数(四舍五入)
+	 * 
+	 * @param num
+	 * @return
+	 */
+	public static String doubleForwardTwo(double num) {
+		return String.format("%.2f", num);
+	}
+
+	/**
+	 * 字符串转换成Ascii
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static String stringToAscii(String value) {
+		StringBuffer sbu = new StringBuffer();
+		char[] chars = value.toCharArray();
+		for (int i = 0; i < chars.length; i++) {
+			if (i != chars.length - 1) {
+				sbu.append((int) chars[i]);
+			} else {
+				sbu.append((int) chars[i]);
+			}
+		}
+		return sbu.toString();
+	}
+
+	/**
+	 * 小数转换为百分比
+	 *  
+	 * @param decimal
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String decTurnPercent(double decimal) {
+		NumberFormat num = NumberFormat.getPercentInstance();
+		num.setMaximumIntegerDigits(3);
+		num.setMaximumFractionDigits(2);
+		return num.format(decimal);
+	}
+
+	/**
+	 * Ascii转换成字符串
+	 * 
+	 * @param value
+	 * @return
+	 */
+	public static String asciiToString(String value) {
+		String[] chars = value.split(",");
+		StringBuffer sbu = new StringBuffer();
+		for (int i = 0; i < chars.length; i++) {
+			sbu.append((char) Integer.parseInt(chars[i]));
+		}
+		return sbu.toString();
+	}
+
+	/**
+	 * 字符串转换unicode
+	 * 
+	 * @param string
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String string2Unicode(String string) {
+		StringBuffer unicode = new StringBuffer();
+		for (int i = 0; i < string.length(); i++) {
+			// 取出每一个字符
+			char c = string.charAt(i);
+			// 转换为unicode
+			unicode.append("\\u" + Integer.toHexString(c));
+		}
+		return unicode.toString();
+	}
+
+	/**
+	 * unicode 转字符串
+	 * 
+	 * @param unicode
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String unicode2String(String unicode) {
+		StringBuffer string = new StringBuffer();
+		String[] hex = unicode.split("\\\\u");
+		for (int i = 1; i < hex.length; i++) {
+			// 转换出每一个代码点
+			int data = Integer.parseInt(hex[i], 16);
+			// 追加成string
+			string.append((char) data);
+		}
+		return string.toString();
+	}
+
+	/**
+	 * 字符串编码转换的实现方法
+	 * 
+	 * @param str
+	 *            待转换编码的字符串
+	 * @param newCharset
+	 *            目标编码
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
+		if (str != null) {
+			// 用默认字符编码解码字符串。
+			byte[] bs = str.getBytes();
+			// 用新的字符编码生成字符串
+			return new String(bs, newCharset);
+		}
+		return null;
+	}
+
+	/**
+	 * 注: \n 回车( ) \t 水平制表符( ) \s 空格(\u0008) \r 换行( )
+	 * 
+	 * @param str
+	 * @return
+	 */
+	public static String replaceBlank(String str) {
+		String dest = "";
+		if (str != null) {
+			Pattern p = Pattern.compile("\\s*|\t|\r|\n");
+			Matcher m = p.matcher(str);
+			dest = m.replaceAll("");
+		}
+		return dest;
+	}
+
+	/**
+	 * 判断该字符串不能为空
+	 * 
+	 * @param str
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static boolean isNotEmpty(Object str) {
+		return !isEmpty(str);
+	}
+	
+	
+	public static boolean isNotEmptyUndefined(Object str) {
+		return !isEmpty(str) && !str.toString().equals("undefined");
+	}
+
+	/**
+	 * 字符串编码转换的实现方法
+	 * 
+	 * @param str
+	 *            待转换编码的字符串
+	 * @param oldCharset
+	 *            原编码
+	 * @param newCharset
+	 *            目标编码
+	 * @return
+	 * @throws UnsupportedEncodingException
+	 */
+	public static String changeCharset(String str, String oldCharset, String newCharset) throws UnsupportedEncodingException {
+		if (str != null) {
+			// 用旧的字符编码解码字符串。解码可能会出现异常。
+			byte[] bs = str.getBytes(oldCharset);
+			// 用新的字符编码生成字符串
+			return new String(bs, newCharset);
+		}
+		return null;
+	}
+
+	/**
+	 * 给手机号码加分割符
+	 * 
+	 * @param phone
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String splitPhone(String phone) {
+		if (isNotEmpty(phone)) {
+			String strone = phone.substring(0, 3);
+			String strtwo = phone.substring(strone.length(), 7);
+			String strthree = phone.substring(strtwo.length() + strone.length(), phone.length());
+			return strone + "-" + strtwo + "-" + strthree;
+		}
+		return "";
+	}
+
+	/**
+	 * 非空判断
+	 * 
+	 * @param str
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static boolean isEmpty(Object str) {
+		return str == null || str.toString().length() == 0 || str.equals("") || str.toString().matches("\\s*");
+	}
+
+	/**
+	 * 把米转换成公里
+	 * 
+	 * @param km
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static Double kmTransKilo(Integer m) {
+		return Math.round(m / 100d) / 10d;
+	}
+	
+	/**
+	 * 将List<{@link Object}>转换成List<{@link T}>
+	 * 
+	 * @param list
+	 *            将要转换的对象
+	 * @param clazs
+	 *            需要转换的泛型对象
+	 * @return
+	 * @author TaoNingBo
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> List<T> fromToObject(List<?> list, Class<T> clazs) {
+		List<T> t = new ArrayList<T>();
+		for (Object object : list) {
+			t.add((T) object);
+		}
+		return t;
+	}
+	
+	 /**
+     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
+     * @return
+     */
+    public static String generateUUID() {
+        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
+    }
+	
+	/**
+	 * 将List<{@link Object}>转换成List<{@link Map<String, Object>}>
+	 * 
+	 * @param list
+	 * @return
+	 * @author TaoNingBo
+	 */
+	@SuppressWarnings("unchecked")
+	public static List<Map<String, Object>> fromToObject_M(List<?> list) {
+		List<Map<String, Object>> t = new ArrayList<Map<String, Object>>();
+		for (Object object : list) {
+			t.add((Map<String, Object>) object);
+		}
+		return t;
+	}
+	
+
+/**
+ * 将对象中的null转换为空
+ * @param obj
+ * @return
+ * @throws IllegalAccessException
+ */
+
+public static  Object checkObjFieldIsNull(Object obj) throws IllegalAccessException {
+	if(obj!=null){
+		for(java.lang.reflect.Field f : obj.getClass().getDeclaredFields()){
+	        f.setAccessible(true);
+	        if(f.get(obj) == null){
+	        	if(f.getType()==String.class){
+	        		f.set(obj, "");
+	        	}
+	        	if(f.getType()==Double.class){
+	        		f.set(obj, 0d);
+	        	}
+	        	if(f.getType()==Integer.class){
+	        		f.set(obj, 0);
+	        	}
+	        	if(f.getType()==Date.class){
+	        		f.set(obj, new Date());
+	        	}
+	        }
+	    }
+		return obj;
+	}
+	return obj;
+}
+/**
+ * 获取六位标识码
+ * @param length
+ * @return
+ */
+public static String createRandomCharData()
+{
+    StringBuilder sb=new StringBuilder();
+    Random rand=new Random();//随机用以下三个随机生成器
+    Random randdata=new Random();
+    int data=0;
+    for(int i=0;i<6;i++)
+    {
+        int index=rand.nextInt(3);
+        //目的是随机选择生成数字,大小写字母
+        switch(index)
+        {
+        case 0:
+             data=randdata.nextInt(10);//仅仅会生成0~9
+             sb.append(data);
+            break;
+        case 1:
+            data=randdata.nextInt(26)+65;//保证只会产生65~90之间的整数
+            sb.append((char)data);
+            break;
+        case 2:
+            data=randdata.nextInt(26)+97;//保证只会产生97~122之间的整数
+            sb.append((char)data);
+            break;
+        }
+    }
+    String result=sb.toString().toLowerCase();
+    return result;
+}
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SpringUtil.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SpringUtil.java
new file mode 100644
index 0000000..7a5564d
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/SpringUtil.java
@@ -0,0 +1,34 @@
+package cn.mb.cloud.gateway.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringUtil implements ApplicationContextAware {
+    @Autowired
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContextParam) throws BeansException {
+        applicationContext = applicationContextParam;
+    }
+    public static Object getObject(String id) {
+        Object object = null;
+        object = applicationContext.getBean(id);
+        return object;
+    }
+    public static <T> T getObject(Class<T> tClass) {
+        return applicationContext.getBean(tClass);
+    }
+
+    public static Object getBean(String tClass) {
+        return applicationContext.getBean(tClass);
+    }
+
+    public <T> T getBean(Class<T> tClass) {
+        return applicationContext.getBean(tClass);
+    }
+}
\ No newline at end of file
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/StringUtil.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/StringUtil.java
new file mode 100644
index 0000000..4ec8eaf
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/StringUtil.java
@@ -0,0 +1,121 @@
+package cn.mb.cloud.gateway.util;
+
+import org.apache.commons.lang.StringUtils;
+
+public class StringUtil {
+
+    /**
+     * 判断字符串中是否包含表情
+     * @param source
+     * @return
+     */
+    public static boolean containsEmoji(String source) {
+        int len = 0;
+        if(null != source){
+            len = source.length();
+        }
+        boolean isEmoji = false;
+        for (int i = 0; i < len; i++) {
+            char hs = source.charAt(i);
+            if (0xd800 <= hs && hs <= 0xdbff) {
+                if (source.length() > 1) {
+                    char ls = source.charAt(i + 1);
+                    int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
+                    if (0x1d000 <= uc && uc <= 0x1f77f) {
+                        return true;
+                    }
+                }
+            } else {
+                // non surrogate
+                if (0x2100 <= hs && hs <= 0x27ff && hs != 0x263b) {
+                    return true;
+                } else if (0x2B05 <= hs && hs <= 0x2b07) {
+                    return true;
+                } else if (0x2934 <= hs && hs <= 0x2935) {
+                    return true;
+                } else if (0x3297 <= hs && hs <= 0x3299) {
+                    return true;
+                } else if (hs == 0xa9 || hs == 0xae || hs == 0x303d
+                        || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c
+                        || hs == 0x2b1b || hs == 0x2b50 || hs == 0x231a) {
+                    return true;
+                }
+                if (!isEmoji && source.length() > 1 && i < source.length() - 1) {
+                    char ls = source.charAt(i + 1);
+                    if (ls == 0x20e3) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return isEmoji;
+    }
+
+    /**
+     * 判断某个字符是不是表情
+     * @param codePoint
+     * @return
+     */
+    private static boolean isEmojiCharacter(char codePoint) {
+        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
+                || (codePoint == 0xD)
+                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
+                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
+                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
+    }
+
+
+    /**
+     * 过滤掉字符串中的表情
+     * @param source
+     * @return
+     */
+    public static String filterEmoji(String source) {
+        if (StringUtils.isBlank(source)) {
+            return source;
+        }
+        StringBuilder buf = null;
+        int len = source.length();
+        for (int i = 0; i < len; i++) {
+            char codePoint = source.charAt(i);
+            if (isEmojiCharacter(codePoint)) {
+                if (buf == null) {
+                    buf = new StringBuilder(source.length());
+                }
+                buf.append(codePoint);
+            }
+        }
+        if (buf == null) {
+            return source;
+        } else {
+            if (buf.length() == len) {
+                buf = null;
+                return source;
+            } else {
+                return buf.toString();
+            }
+        }
+    }
+
+
+    /**
+     * 判断字符串为空
+     * @param value
+     * @return
+     */
+    public static boolean isEmpty(String value){
+        if(null == value || value.trim().equals("")){
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断字符串非空
+     * @param value
+     * @return
+     */
+    public static boolean isNotEmpty(String value){
+        return !isEmpty(value);
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/CacheType.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/CacheType.java
new file mode 100644
index 0000000..c47d65f
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/CacheType.java
@@ -0,0 +1,86 @@
+package cn.mb.cloud.gateway.util.applets;
+
+/**
+ * 缓存消息类型
+ * 
+ * @author TaoNingBo
+ * @data 2016年9月21日
+ * @version 1.0
+ */
+public class CacheType {
+	
+	/**
+	 * 用户通讯通道标识
+	 */
+	public static final String userCtx = "USER_CTX_";
+	
+	/**
+	 * 司机通讯通道标识
+	 */
+	public static final String driverCtx = "DRIVER_CTX_";
+
+	/**
+	 * 出行-快车/专车/代驾-订单消息队列-自营车辆
+	 */
+	public static final String travelOrder1 = "TRAVEL_ORDER1_";
+	
+	/**
+	 * 出行-快车/专车/代驾-订单消息队列-外来车辆
+	 */
+	public static final String travelOrder2 = "TRAVEL_ORDER2_";
+	
+	/**
+	 * 快车-司机位置-自营车辆
+	 */
+	public static final String location1 = "_LOCATION1";
+	
+	/**
+	 * 快车-司机位置-外来车辆
+	 */
+	public static final String location2 = "_LOCATION2";
+	
+	/**
+	 * 快车-司机抢单成功后的消息
+	 */
+	public static final String travelOrder = "TRAVEL_ORDER_";
+	
+	/**
+	 * 开始服务时间
+	 */
+	public static final String startServerT = "START_SERVER_TIME_";
+	
+	/**
+	 * 司机上一次的位置(经纬度)
+	 */
+	public static final String location = "LAST_DRIVER_LOCATION_";
+	
+	/**
+	 * 司机上一次总共行驶距离
+	 */
+	public static final String triverd = "LAST_TRIVER_Distance_";
+	
+	/**
+	 * 记录订单数据 司机 异常处理
+	 */
+	public static final String dreco = "DRIVER_DATA_RECO";
+	
+	/**
+	 * 记录订单数据 用户  异常处理
+	 */
+	public static final String ureco = "USER_DATA_RECO";
+	
+	/** 
+	 * 记录司机跟用户的关系ID
+	 */
+	public final static String udID = "USER_DRIVER_ID_";
+	
+	/**
+	 * 记录下单乘客的出发点位置坐标
+	 */
+	public final static String userLoc = "USER_LOCATION_";
+	
+	/**
+	 * 记录计费规则【用订单号获取】
+	 */
+	public final static String rules = "RULES_ORDER_";
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ChildChannelHandler.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ChildChannelHandler.java
new file mode 100644
index 0000000..59c929f
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ChildChannelHandler.java
@@ -0,0 +1,36 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.codec.http.HttpObjectAggregator;
+import io.netty.handler.codec.http.HttpServerCodec;
+import io.netty.handler.ssl.SslHandler;
+import io.netty.handler.stream.ChunkedWriteHandler;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+
+public class ChildChannelHandler extends ChannelInitializer<SocketChannel> {
+    @Override
+    protected void initChannel(SocketChannel socketChannel) throws Exception {
+        String path = "D:\\Program Files\\Apache Software Foundation\\Tomcat 8.5-80\\cert\\6855055_zhentonggongsi.com.pfx";
+//        String path = "/usr/local/server/apache-tomcat-80/conf/cert/6064978_okyueche.com.pfx";
+        SSLContext sslContext = createSSLContext.createSSLContext("PKCS12"
+                , path, "jBOjj2fR");
+        //SSLEngine 此类允许使用ssl安全套接层协议进行安全通信
+        SSLEngine engine = sslContext.createSSLEngine();
+        engine.setUseClientMode(false);
+        socketChannel.pipeline().addLast("ssl", new SslHandler(engine));
+
+        // 设置30秒没有读到数据,则触发一个READER_IDLE事件。
+        // pipeline.addLast(new IdleStateHandler(30, 0, 0));
+        // HttpServerCodec:将请求和应答消息解码为HTTP消息
+        socketChannel.pipeline().addLast("http-codec", new HttpServerCodec());
+        // HttpObjectAggregator:将HTTP消息的多个部分合成一条完整的HTTP消息
+        socketChannel.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));
+        // ChunkedWriteHandler:向客户端发送HTML5文件
+        socketChannel.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
+        // 在管道中添加我们自己的接收数据实现方法
+        socketChannel.pipeline().addLast("handler", new WebSocketHandler());
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ClientPingMessage.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ClientPingMessage.java
new file mode 100644
index 0000000..7640fdd
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/ClientPingMessage.java
@@ -0,0 +1,59 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import java.io.Serializable;
+
+/**
+ * 客户端心跳消息处理
+ * 
+ * @author TaoNingBo
+ * @data 2016年7月26日
+ * @version 1.0
+ */
+public class ClientPingMessage implements Serializable {
+
+	private static final long serialVersionUID = -4953410803742767757L;
+
+	/**
+	 * 客户端标识ID
+	 */
+	private Integer id;
+	
+	/**
+	 * 角色【0:用户,1:司机】
+	 */
+	private Integer role;
+	
+	/**
+	 * 客户端单点登录标识TOKEN
+	 */
+	private String token;
+	
+	public ClientPingMessage() {
+		
+	}
+
+	public Integer getId() {
+		return id;
+	}
+
+	public void setId(Integer id) {
+		this.id = id;
+	}
+
+	public Integer getRole() {
+		return role;
+	}
+
+	public void setRole(Integer role) {
+		this.role = role != null ? role : 0;
+	}
+
+	public String getToken() {
+		return token;
+	}
+
+	public void setToken(String token) {
+		this.token = token;
+	}
+	
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/Global.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/Global.java
new file mode 100644
index 0000000..a16897a
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/Global.java
@@ -0,0 +1,9 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import io.netty.channel.group.ChannelGroup;
+import io.netty.channel.group.DefaultChannelGroup;
+import io.netty.util.concurrent.GlobalEventExecutor;
+
+public class Global {
+    public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyServer0.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyServer0.java
new file mode 100644
index 0000000..40486de
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyServer0.java
@@ -0,0 +1,77 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+
+/**
+ * 即时通讯服务启动类
+ * 
+ * @date 2016年6月25日
+ * @version 1.0
+ */
+public class NettyServer0 {
+
+	/**
+	 * 延迟启动设置
+	 * 
+	 * NettyServer启动方法.
+	 */
+	public void bind() {
+		final Thread thread = new Thread(new NettyRunnable());
+		Timer timer = new Timer();
+		timer.schedule(new TimerTask() {
+			@Override
+			public void run() {
+				thread.start();
+			}
+		}, 1000 * 2);
+	}
+	
+	/**
+	 * 即时通讯服务启动
+	 * 
+	 * @date 2016年6月24日
+	 * @version 1.0
+	 */
+	public class NettyRunnable implements Runnable {
+		
+		/**
+		 * 获取即时通讯启动端口 
+		 */
+		@Override
+		public void run() {
+			System.out.println("===========================Netty端口启动========");
+			// Boss线程:由这个线程池提供的线程是boss种类的,用于创建、连接、绑定socket,
+			// (有点像门卫)然后把这些socket传给worker线程池。
+			// 在服务器端每个监听的socket都有一个boss线程来处理。在客户端,只有一个boss线程来处理所有的socket。
+			EventLoopGroup bossGroup = new NioEventLoopGroup();
+			// Worker线程:Worker线程执行所有的异步I/O,即处理操作
+			EventLoopGroup workrGroup = new NioEventLoopGroup();
+			try {
+
+				// ServerBootstrap 启动NIO服务的辅助启动类,负责初始话netty服务器,并且开始监听端口的socket请求
+				ServerBootstrap b = new ServerBootstrap();
+				b.group(bossGroup, workrGroup);
+				// 设置非阻塞,用它来建立新accept的连接,用于构造serversocketchannel的工厂类
+				b.channel(NioServerSocketChannel.class);
+				// ChildChannelHandler 对出入的数据进行的业务操作,其继承ChannelInitializer
+				b.childHandler(new ChildChannelHandler());
+				System.out.println("服务端开启等待客户端连接 ... ...");
+				Channel ch = b.bind(9090).sync().channel();
+				ch.closeFuture().sync();
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				bossGroup.shutdownGracefully();
+				workrGroup.shutdownGracefully();
+			}
+		}
+	}
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyWebSocketController.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyWebSocketController.java
new file mode 100644
index 0000000..8bd7a5c
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/NettyWebSocketController.java
@@ -0,0 +1,205 @@
+package cn.mb.cloud.gateway.util.applets;
+
+
+import cn.mb.cloud.gateway.util.RedisUtil;
+import cn.mb.cloud.gateway.util.SinataUtil;
+import cn.mb.cloud.gateway.util.SpringUtil;
+import cn.mb.cloud.gateway.util.StringUtil;
+import cn.mb.cloud.gateway.util.echo.Method;
+import cn.mb.cloud.gateway.util.echo.NettyChannelMap;
+import com.alibaba.fastjson.JSONObject;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
+
+import java.util.Hashtable;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class NettyWebSocketController {
+
+    public static Hashtable<String, Hashtable<ChannelHandlerContext, String>> map = new Hashtable<String, Hashtable<ChannelHandlerContext, String>>();
+
+    private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class);
+
+    public static Hashtable<String, String> table;
+
+    static {
+        if (table == null) {
+            table = new Hashtable<>();
+        }
+    }
+
+    public static boolean isdebug = false;
+    public static int i = 0;
+
+
+    /**
+     * 判断客户端要执行什么操作
+     *
+     * @param ctx
+     * @param msg
+     * @author TaoNingBo
+     */
+    public void JudgeOperation(ChannelHandlerContext ctx, String msg) {
+        try {
+            // 验证即时通讯命令是否正确有效
+            if (SinataUtil.isEmpty(msg)) {
+                return;
+            }
+            String msgStr = msg.toString();
+            if (msgStr.indexOf("{") == -1 || msgStr.indexOf("}") == -1 || msgStr.indexOf("code") == -1 || msgStr.indexOf("msg") == -1 || msgStr.indexOf("data") == -1 || msgStr.indexOf("method") == -1) {
+                return;
+            }
+            if (isdebug) {
+//            System.out.println("<<<--receive-->>>111" + msg);
+            }
+
+            // 获取socket信息,保存相应的socket
+            JSONObject jsonMsg = JSONObject.parseObject(msg.toString());
+            int code = jsonMsg.getIntValue("code");
+            String message = jsonMsg.getString("msg");
+            String method = jsonMsg.getString("method");
+            if (code != 200 || !message.equals("SUCCESS")) {
+                return;
+            }
+            JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString());
+
+            if (null != ctx && ctx.channel().isActive()) {
+                jsonMsg.put("method", Method.pong);
+                sendMsgToClient(ctx, jsonMsg.toJSONString());
+            }
+
+
+            // ############################### 心跳  ############################
+            // 心跳
+            if (method.equals(Method.ping)) {
+                String token = jsonCon.getString("token");
+                String userId1 = jsonCon.getString("userId");
+                if (StringUtil.isNotEmpty(userId1)) {
+                    //确保账号在单个设备上登录
+                    if (StringUtil.isNotEmpty(token)) {
+                        NettyChannelMap.update_(token.substring(0, 23), ctx);//存储单点登录的通道
+                        String token_ = redisUtil.getValue("USER_Applets_" + userId1);//获取缓存中最新的数据
+                        if (StringUtil.isNotEmpty(token_) && !token.equals(token_)) {//不在同一设备上登录,向其他设备发送数据
+                            JSONObject msg_ = new JSONObject();
+                            msg_.put("code", 200);
+                            msg_.put("msg", "SUCCESS");
+                            msg_.put("method", "OFFLINE");
+                            msg_.put("data", new Object());
+                            this.sendMsgToClient(ctx, msg_.toJSONString());
+                            TimerTask timerTask = new TimerTask() {
+                                @Override
+                                public void run() {
+                                    NettyChannelMap.remove_(ctx);
+                                }
+                            };
+                            Timer timer = new Timer();
+                            timer.schedule(timerTask, 3000);
+                            timer.cancel();
+                        }
+                        if (StringUtil.isEmpty(token_)) {//确保登录的时候存储token失败的情况
+                            redisUtil.setStrValue("USER_Applets_" + userId1, token);
+                        }
+                    }
+
+                    //存储业务使用的通道
+                    if (null != ctx && ctx.channel().isActive()) {
+                        NettyChannelMap.update("Applets" + userId1, ctx);
+//                    String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+//                    ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes()));
+                    }
+                }
+
+
+            }
+        } catch (Exception e) {
+            if (isdebug) {
+                NettyWebSocketController.sendMsgToClient(ctx, "__error__" + msg.toString());
+            }
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 向客户端发送消息
+     *
+     * @param ctx
+     * @param msg
+     * @author TaoNingBo
+     */
+    public static void sendMsgToClient(ChannelHandlerContext ctx, String msg) {
+//        System.out.println(ctx.channel().isActive());
+        if (ctx != null && ctx.channel().isActive()) {
+            ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes());
+            ChannelFuture sync;
+            try {
+                sync = ctx.channel().writeAndFlush(new TextWebSocketFrame(msg)).sync();
+                if (!sync.isSuccess()) {
+                    boolean b = true;
+                    for (int i = 0; i < 10; i++) {
+                        ctx.wait(3000);
+                        sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();
+                        if (sync.isSuccess()) {
+                            b = false;
+                            break;
+                        }
+                        System.err.println("小程序-》推送不成功,将继续推送" + msg);
+                    }
+                    if (b) {
+                        NettyChannelMap.remove(ctx);
+                    }
+                }
+            } catch (Exception e) {
+                System.err.println("小程序-》推送发生异常,记录:" + msg);
+                NettyChannelMap.remove(ctx);
+            }
+            if (isdebug) {
+                System.err.println("小程序-》 <<<--send-->>>" + msg);
+            }
+        } else {
+            System.err.println("小程序-》推送失败,长连接不存在");
+            NettyChannelMap.remove(ctx);
+        }
+    }
+
+    //	**链接断开 将推送消息记录
+    public static void sendMsgToClient(String cacheType, Integer id, String msg) {
+        ChannelHandlerContext ctx = NettyChannelMap.getData(cacheType + id);
+        if (ctx != null) {
+            ChannelFuture sync;
+            try {
+                sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();
+                if (!sync.isSuccess()) {
+                    for (int i = 0; i < 10; i++) {
+                        sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();
+                        ;
+                        if (!sync.isSuccess()) {
+                            sync = ctx.channel().write(new TextWebSocketFrame(msg)).sync();
+                            ;
+                            System.err.println("推送不成功,将继续推送" + msg);
+                            if (i == 9) {
+                                table.put(cacheType + id, msg);
+                                ctx.close();
+                                System.err.println("推送发生异常,记录:" + msg);
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                }
+            } catch (Exception e) {
+                table.put(cacheType + id, msg);
+                System.err.println("推送发生异常,记录:" + msg);
+            }
+            if (isdebug) {
+                System.err.println("<<<--send-->>>" + msg);
+            }
+        } else {
+            table.put(cacheType + id, msg);
+            System.err.println("链接断开,记录:id=" + cacheType + id + ",消息:" + msg);
+        }
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/WebSocketHandler.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/WebSocketHandler.java
new file mode 100644
index 0000000..876dde0
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/WebSocketHandler.java
@@ -0,0 +1,180 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import cn.mb.cloud.gateway.util.echo.Method;
+import cn.mb.cloud.gateway.util.echo.NettyChannelMap;
+import cn.mb.cloud.gateway.util.echo.NettyMsg;
+import com.alibaba.fastjson.JSONObject;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.http.*;
+import io.netty.handler.codec.http.websocketx.*;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.util.CharsetUtil;
+
+import java.util.HashMap;
+
+
+public class WebSocketHandler extends SimpleChannelInboundHandler<Object> {
+    //用于websocket握手的处理类
+    private WebSocketServerHandshaker handshaker;
+
+    private static final String WEB_SOCKET_URL = "wss://localhost:9090/websocket";
+
+
+
+//   @Override
+//    protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
+//        if (msg instanceof FullHttpRequest) {
+//            // websocket连接请求
+//            handleHttpRequest(ctx, (FullHttpRequest)msg);
+//        } else if (msg instanceof WebSocketFrame) {
+//            // websocket业务处理
+//            handleWebSocketRequest(ctx, (WebSocketFrame)msg);
+//        }
+//    }
+
+    @Override
+    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+        ctx.flush();
+    }
+
+    /** 心跳 */
+    @Override
+    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+        if (evt instanceof IdleStateEvent) {
+            IdleStateEvent event = (IdleStateEvent) evt;
+            if (event.state().equals(IdleState.READER_IDLE))
+            {
+                //
+            }
+            else if (event.state().equals(IdleState.WRITER_IDLE))
+            {
+                //
+            }
+            else if (event.state().equals(IdleState.ALL_IDLE))
+            {
+                String msg = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+                if(ctx != null && ctx.channel().isActive()) {
+                    ctx.writeAndFlush(Unpooled.copiedBuffer((msg).getBytes()));
+                }
+            }
+        }
+//        super.userEventTriggered(ctx, evt);
+    }
+
+    @Override
+    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
+        ctx.close();
+    }
+
+    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
+        // Http解码失败,向服务器指定传输的协议为Upgrade:websocket
+        if(!req.getDecoderResult().isSuccess() || !("websocket").equals(req.headers().get("Upgrade"))){
+            sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
+            return;
+        }
+        // 握手相应处理,创建websocket握手的工厂类,
+        WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(WEB_SOCKET_URL, null, false);
+        // 根据工厂类和HTTP请求创建握手类
+        handshaker = wsFactory.newHandshaker(req);
+        if (handshaker == null) {
+            // 不支持websocket
+            WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
+        } else {
+            // 通过它构造握手响应消息返回给客户端
+            handshaker.handshake(ctx.channel(), req);
+        }
+    }
+
+    private void handleWebSocketRequest(ChannelHandlerContext ctx, WebSocketFrame req) throws Exception {
+        if (req instanceof CloseWebSocketFrame) {
+            // 关闭websocket连接
+            handshaker.close(ctx.channel(), (CloseWebSocketFrame)req.retain());
+            return;
+        }
+        if (req instanceof PingWebSocketFrame) {
+            ctx.channel().write(new PongWebSocketFrame(req.content().retain()));
+            return;
+        }
+        if (!(req instanceof TextWebSocketFrame)) {
+            throw new UnsupportedOperationException("当前只支持文本消息,不支持二进制消息");
+        }
+        if (ctx == null || this.handshaker == null || ctx.isRemoved()) {
+            throw new Exception("尚未握手成功,无法向客户端发送WebSocket消息");
+        }
+        String requestmsg = ((TextWebSocketFrame) req).text();
+
+
+        //给连接的客户端返回数据
+        //返回心跳
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("code", 200);
+        jsonObject.put("method", Method.ok);
+        jsonObject.put("msg", "SUCCESS");
+        jsonObject.put("data", new JSONObject());
+        TextWebSocketFrame tws = new TextWebSocketFrame(jsonObject.toJSONString());
+//        ctx.channel().writeAndFlush(tws);
+
+        new NettyWebSocketController().JudgeOperation(ctx,requestmsg);//小程序心跳处理
+
+        // 群发服务端心跳响应
+        Global.group.writeAndFlush(new TextWebSocketFrame((tws).text()));
+    }
+
+    private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req, FullHttpResponse res) {
+        // BAD_REQUEST(400) 客户端请求错误返回的应答消息
+        if(res.getStatus().code() != 200){
+            ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
+            res.content().writeBytes(buf);
+            buf.release();
+        }
+        //服务端向客户端发送数据
+        ChannelFuture f = ctx.channel().writeAndFlush(res);
+        // 非法连接直接关闭连接
+        if(res.getStatus().code() != 200){
+            f.addListener(ChannelFutureListener.CLOSE);
+        }
+    }
+
+
+    @Override
+    public void channelActive(ChannelHandlerContext ctx) throws Exception {
+        Global.group.add(ctx.channel());
+        System.err.println("客户端与服务器端开启");
+    }
+
+    @Override
+    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+        Global.group.remove(ctx.channel());
+        NettyChannelMap.remove(ctx);
+        System.err.println("客户端与服务器链接关闭");
+    }
+
+
+    @Override
+    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
+        if (msg instanceof FullHttpRequest) {
+            // websocket连接请求
+            handleHttpRequest(ctx, (FullHttpRequest)msg);
+        } else if (msg instanceof WebSocketFrame) {
+            // websocket业务处理
+            handleWebSocketRequest(ctx, (WebSocketFrame)msg);
+        }
+    }
+
+    @Override
+    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
+        if (msg instanceof FullHttpRequest) {
+            // websocket连接请求
+            handleHttpRequest(ctx, (FullHttpRequest)msg);
+        } else if (msg instanceof WebSocketFrame) {
+            // websocket业务处理
+            handleWebSocketRequest(ctx, (WebSocketFrame)msg);
+        }
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/createSSLContext.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/createSSLContext.java
new file mode 100644
index 0000000..cdfc246
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/applets/createSSLContext.java
@@ -0,0 +1,31 @@
+package cn.mb.cloud.gateway.util.applets;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.security.KeyStore;
+
+public class createSSLContext {
+
+    /**
+     * 获取SSLContext
+     * @param type
+     * @param path
+     * @param password
+     * @return
+     * @throws Exception
+     */
+    public static SSLContext createSSLContext(String type , String path , String password) throws Exception {
+        KeyStore ks = KeyStore.getInstance(type); /// "JKS"
+        InputStream ksInputStream = new FileInputStream(path); /// 证书存放地址
+        ks.load(ksInputStream, password.toCharArray());
+        //KeyManagerFactory充当基于密钥内容源的密钥管理器的工厂。
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());//getDefaultAlgorithm:获取默认的 KeyManagerFactory 算法名称。
+        kmf.init(ks, password.toCharArray());
+        //SSLContext的实例表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂。
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(kmf.getKeyManagers(), null, null);
+        return sslContext;
+    }
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/DiscardServerHandler.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/DiscardServerHandler.java
new file mode 100644
index 0000000..37f79a1
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/DiscardServerHandler.java
@@ -0,0 +1,153 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.timeout.IdleState;
+import io.netty.handler.timeout.IdleStateEvent;
+import io.netty.util.ReferenceCountUtil;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+
+public class DiscardServerHandler extends SimpleChannelInboundHandler<String>  {
+
+	private NettyServerController nettyServerController = new NettyServerController();
+	
+	public static boolean isdebug = true;
+
+	@Override
+	public void channelRead(ChannelHandlerContext ctx, Object msg) {
+		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+		if(isdebug) {
+//			System.err.println(insocket.getAddress() + ": 收到客户端数据.......");
+		}
+		try {
+			// 调用service
+			nettyServerController.JudgeOperation(ctx, msg);
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			ReferenceCountUtil.release(msg);
+		}
+	}
+
+	@Override
+	protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
+		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+		if(isdebug) {
+//			System.err.println(insocket.getAddress() + ": 收到客户端数据.......");
+		}
+		try {
+			// 调用service
+			nettyServerController.JudgeOperation(ctx, msg);
+		} catch (Exception e) {
+			e.printStackTrace();
+		} finally {
+			ReferenceCountUtil.release(msg);
+		}
+	}
+
+//	@Override
+//	protected void messageReceived(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
+//
+//	}
+
+//	@Override
+//	protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
+//
+//	}
+
+//	@Override
+//	protected void messageReceived(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
+//
+//	}
+
+	/** 在连接被建立并且准备进行通信时被调用 */
+	public void channelActive(final ChannelHandlerContext ctx) throws Exception {
+		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+		if(isdebug) {
+//			System.err.println(insocket.getAddress() + ": Connect successful......");
+		}
+	}
+
+	/** 心跳 */
+	@Override
+	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
+		if (evt instanceof IdleStateEvent) {
+			IdleStateEvent event = (IdleStateEvent) evt;
+			if (event.state().equals(IdleState.READER_IDLE))
+			{
+				//
+			} 
+			else if (event.state().equals(IdleState.WRITER_IDLE)) 
+			{
+				//
+			} 
+			else if (event.state().equals(IdleState.ALL_IDLE))
+			{
+				String msg = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+				if(ctx != null && ctx.channel().isActive()) {
+					ctx.writeAndFlush(Unpooled.copiedBuffer((msg).getBytes()));
+//					System.err.println(msg);
+				}
+			}
+		}
+		//super.userEventTriggered(ctx, evt);
+	}
+
+	/** 连接处于不活跃时调用(连接关闭) **/
+	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
+		if(isdebug) {
+			InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+//			System.err.println(insocket.getAddress() + ": Disconnect connection......");
+		}
+		NettyChannelMap.remove(ctx);
+//		System.err.println("清除通道" + ctx);
+//		super.channelInactive(ctx);
+	}
+
+	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
+		ctx.flush();
+	}
+
+	/** 处理方法是当出现Throwable对象才会被调用 **/
+	public void exceptionCaught(ChannelHandlerContext ctx,Throwable cause) throws Exception {
+		ctx.close();
+	}
+
+	public void close(ChannelHandlerContext ctx, ChannelPromise promise) throws Exception {
+		if(isdebug) {
+			InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+//			System.err.println("close......." + insocket.getAddress());
+		}
+		ctx.close(promise);
+	}
+
+	public void read(ChannelHandlerContext ctx) throws Exception {
+		ctx.read();
+	}
+
+	public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
+		ctx.write(msg, promise);
+	}
+
+//	@Override
+//	protected void channelRead(ChannelHandlerContext ctx, String msg) throws Exception {
+//		// TODO Auto-generated method stub
+//		InetSocketAddress insocket = (InetSocketAddress) ctx.channel().remoteAddress();
+//		if(isdebug) {
+//			System.out.println(insocket.getAddress() + ": 收到客户端数据.......");
+//		}
+//		try {
+//			// 调用service
+//			nettyServerController.JudgeOperation(ctx, msg);
+//		} catch (Exception e) {
+//			e.printStackTrace();
+//		} finally {
+//			ReferenceCountUtil.release(msg);
+//		}
+//	}
+	
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/Method.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/Method.java
new file mode 100644
index 0000000..be79edc
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/Method.java
@@ -0,0 +1,26 @@
+package cn.mb.cloud.gateway.util.echo;
+
+/**
+ * 即时通讯【通讯类型类】
+ * 
+ * @author TaoNingBo
+ * @createDate 2016年6月14日
+ * @version 1.0
+ */
+public class Method {
+	
+	/** 心跳【推送】 */
+	public static final String ok = "OK";
+
+	/** 心跳【接收】 */
+	public final static String ping = "PING";
+
+	/** 心跳【响应】 */
+	public final static String pong = "PONG";
+
+	/** 司机上传位置 */
+	public static final String location = "LOCATION";
+
+
+	
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyChannelMap.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyChannelMap.java
new file mode 100644
index 0000000..1e42cb4
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyChannelMap.java
@@ -0,0 +1,133 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import io.netty.channel.ChannelHandlerContext;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class NettyChannelMap {
+
+	protected static Map<String, ChannelHandlerContext> map = new ConcurrentHashMap<>();
+
+	public static Map<String, ChannelHandlerContext> ctxMap = new HashMap<>();//单点登录存储的通道
+
+
+	private NettyChannelMap() {
+		// 放置外部实例化
+	}
+	
+	/**
+	 * Get data from source.
+	 * 
+	 * @param key
+	 * @return
+	 */
+	public static ChannelHandlerContext getData(String key) {
+		if(map==null){
+			map = new HashMap<String, ChannelHandlerContext>();
+		}
+		return map.get(key);
+	}
+
+
+	public static ChannelHandlerContext getData_(String key) {
+		if(ctxMap==null){
+			ctxMap = new HashMap<String, ChannelHandlerContext>();
+		}
+		return ctxMap.get(key);
+	}
+
+	
+	/**
+	 * Save data from source.
+	 * 
+	 * @param key
+	 * @param val
+	 */
+	public static synchronized void saveData(String key, ChannelHandlerContext val) {
+		map.put(key, val);
+	}
+	
+	/**
+	 * Determine whether the cache key contains the key.
+	 * 
+	 * @param key
+	 * @return	true|false
+	 * @author TaoNingBo
+	 */
+	public static synchronized boolean containsKey(String key) {
+		return map.containsKey(key);
+	}
+	
+	/**
+	 * Determine whether the cache value contains the value.
+	 * 
+	 * @param val
+	 * @return
+	 */
+	public static synchronized boolean containsVal(ChannelHandlerContext val) {
+		return map.containsValue(val);
+	}
+	
+	/**
+	 * Remove the data resources.
+	 * 
+	 * @param value
+	 */
+	@SuppressWarnings("rawtypes")
+	public static synchronized void remove(ChannelHandlerContext value) {
+		Set<String> strings = map.keySet();
+		for(String key : strings){
+			ChannelHandlerContext channelHandlerContext = map.get(key);
+			String s = channelHandlerContext.channel().remoteAddress().toString();
+			String s1 = value.channel().remoteAddress().toString();
+			if(s.equals(s1)){
+				channelHandlerContext.close();//关闭通道
+				map.remove(key);
+			}
+		}
+	}
+
+
+	public static synchronized void remove_(ChannelHandlerContext value) {
+		Set<String> strings = ctxMap.keySet();
+		for(String key : strings){
+			ChannelHandlerContext channelHandlerContext = ctxMap.get(key);
+			String s = channelHandlerContext.channel().remoteAddress().toString();
+			String s1 = value.channel().remoteAddress().toString();
+			if(s.equals(s1)){
+				channelHandlerContext.close();//关闭通道
+				ctxMap.remove(key);
+			}
+		}
+	}
+
+	
+	/**
+	 * Remove the data resources.
+	 * 
+	 * @param key
+	 * @author TaoNingBo
+	 */
+	public static synchronized void remove(String key) {
+		map.remove(key);
+	}
+	
+	/**
+	 * Update the data resources.
+	 * 
+	 * @param key
+	 * @param value
+	 */
+	public static synchronized void update(String key, ChannelHandlerContext value) {
+		map.put(key, value);
+	}
+
+
+
+	public static synchronized void update_(String key, ChannelHandlerContext value) {
+		ctxMap.put(key, value);
+	}
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyMsg.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyMsg.java
new file mode 100644
index 0000000..665fb61
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyMsg.java
@@ -0,0 +1,165 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+
+public class NettyMsg {
+	public static void main(String[] args) {
+		Map<String,Object> map = new HashMap<String, Object>();
+		//用户信息
+		map.put("imgUrl","1");
+		map.put("nickName","1");
+		map.put("licensePlate","1");
+		map.put("phone",1);
+		map.put("driverId",1);
+		map.put("carColor","1");
+		map.put("modelName","1");
+		map.put("brandName","1");
+		map.put("driverOrderNums",1);
+		map.put("score",1);
+		
+		
+		map.put("id",1);
+		map.put("orderNum", "123456");
+		map.put("startAddress", "测试");
+		map.put("endAddress", "测试1");
+		map.put("departureTime", 1533608196000L);
+		map.put("type",1);
+		map.put("mileage",1);
+		map.put("mileageMoney",10);
+		map.put("duration",10);
+		map.put("durationMoney",10);
+		map.put("nightMoney",1);
+		map.put("serverMoney",1);
+		map.put("nightMileage",10);
+		map.put("longMileage",10);
+		map.put("longDurationMoney",10);
+		map.put("orderMoney",10);
+		map.put("payMoney",10);
+		map.put("couponsMoney",10);
+		System.out.println(setMsg(Method.ping, new HashMap<String, Object>()));
+	}
+	
+	/**
+	 * 返回一个正确数据
+	 * 
+	 * @param method
+	 * @param data
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String setMsg(String method, Map<String, Object> data) {
+		StringBuffer json = new StringBuffer();
+		json.append(getHeader(200, "SUCCESS", method));
+		json.append(JSON.toJSONString(data));
+		json.append("}");
+		//return JSON.toJSONString(json);
+		return json.toString();
+	}
+	
+	/**
+	 * 返回一个正确数据
+	 * 
+	 * @param method
+	 * @param data
+	 * @return
+	 */
+	public static String setMsg(String method, List<Map<String, Object>> data) {
+		StringBuffer json = new StringBuffer();
+		json.append(getHeader(200, "SUCCESS", method));
+		List<JSONObject> jsonList = new ArrayList<JSONObject>();
+		for(Map<String, Object> map : data) {
+			JSONObject dataJson = new JSONObject(map);
+			jsonList.add(dataJson);
+		}
+		json.append(jsonList);
+		json.append("}");
+		
+//		return JSON.toJSONString(json);
+		return json.toString();
+	}
+	
+	/**
+	 * 返回一个错误数据
+	 * 
+	 * @param method
+	 * @param data
+	 * @return
+	 * @author TaoNingBo
+	 */
+	public static String setErrMsg(String method, String data) {
+		StringBuffer json = new StringBuffer();
+		json.append(getHeader(-1, "FAILURE", method));
+		json.append("\"" + data + "\"");
+		json.append("}");
+//		return JSON.toJSONString(json);
+		return json.toString();
+	}
+	
+	/**
+	 * 生成一个返回JSON的头
+	 * 
+	 * @param code
+	 * @param msg
+	 * @param method
+	 * @return
+	 * @author TaoNingBo
+	 */
+	private static String getHeader(int code, String msg, String method) {
+		StringBuffer header = new StringBuffer();
+		header.append("{");
+		header.append("\"code\":\"" + code);
+		header.append("\",\"msg\":\"" + msg);
+		header.append("\",\"method\":\"" + method);
+		header.append("\",\"data\":");
+		return header.toString();
+	}
+	
+	/**
+	 * 发送消息给客户端
+	 * 
+	 * @param cacheType
+	 * @param id
+	 * @param method
+	 * @param data
+	 * @author TaoNingBo
+	 */
+	public static void sendMsg(String cacheType, Integer id, String method, Map<String, Object> data) {
+		//NettyServerController.sendMsgToClient(NettyChannelMap.getData(cacheType + id), setMsg(method, data));
+		NettyServerController.sendMsgToClient(cacheType,id, setMsg(method, data));
+	}
+
+
+	public static void resendMsg(String token){
+		String msg = NettyServerController.table.get(token);
+		ChannelHandlerContext ctx = NettyChannelMap.getData(token);
+		if(null != msg && !"".equals(msg) && ctx != null && ctx.channel().isActive()){
+			ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes());
+			ChannelFuture sync;
+			try {
+				sync = ctx.writeAndFlush(buffer).sync();
+				System.err.println("重发异常推送状态"+sync.isSuccess()+",位置:"+token+",消息内容:"+msg);
+				if(!sync.isSuccess()){
+					resendMsg(token);
+					System.err.println("重发异常推送不成功,将继续推送"+msg);
+				}
+				NettyServerController.table.remove(token);
+			} catch (Exception e) {
+				resendMsg(token);
+				System.err.println("重发推送发生异常,记录:"+msg);
+			}
+		}
+	}
+
+
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServer.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServer.java
new file mode 100644
index 0000000..a9bbb7b
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServer.java
@@ -0,0 +1,95 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import io.netty.bootstrap.ServerBootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.EventLoopGroup;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.netty.handler.codec.LengthFieldPrepender;
+import io.netty.handler.timeout.IdleStateHandler;
+
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 即时通讯服务启动类
+ *
+ * @date 2016年6月25日
+ * @version 1.0
+ */
+public class NettyServer {
+
+
+	/**
+	 * NettyServer启动方法.
+	 */
+	public void bind() {
+		final Thread thread = new Thread(new NettyRunnable());
+		Timer timer = new Timer();
+		timer.schedule(new TimerTask() {
+			@Override
+			public void run() {
+				thread.start();
+			}
+		}, 10000);
+	}
+
+	/**
+	 * 即时通讯服务启动
+	 *
+	 * @date 2016年6月24日
+	 * @version 1.0
+	 */
+	public class NettyRunnable implements Runnable {
+
+		/**
+		 * 获取即时通讯启动端口 
+		 */
+		private Integer nettyPort = 8888;
+		@Override
+		public void run() {
+			EventLoopGroup bossGroup = new NioEventLoopGroup();
+			EventLoopGroup workerGroup = new NioEventLoopGroup();
+			try {
+				ServerBootstrap bootstrap = new ServerBootstrap();
+				bootstrap.group(bossGroup, workerGroup);
+				bootstrap.channel(NioServerSocketChannel.class);
+				bootstrap.option(ChannelOption.SO_BACKLOG, 1024);
+				// 通过TCP_NODELAY禁用NAGLE,使消息立即发出去,不用等待到一定的数据量才发出去
+				bootstrap.option(ChannelOption.TCP_NODELAY, true);
+				// 保持长连接状态
+				bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
+				bootstrap.childHandler(new ServerInit() {
+					@Override
+					protected void initChannel(SocketChannel socketChannel) throws Exception {
+						ChannelPipeline pipeline = socketChannel.pipeline();
+						pipeline.addLast("ping", new IdleStateHandler(120, 60, 5, TimeUnit.SECONDS));
+						pipeline.addLast("decoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
+						pipeline.addLast("encoder", new LengthFieldPrepender(4));
+						//pipeline.addLast(new LineBasedFrameDecoder(1048576 * 10));
+						//pipeline.addLast(new StringDecoder(Charset.forName("UTF-8")));
+						//pipeline.addLast(new StringEncoder(Charset.forName("UTF-8")));
+						pipeline.addLast(new DiscardServerHandler());
+					}
+				});
+				// 服务器绑定端口监听
+				ChannelFuture f = bootstrap.bind(nettyPort).sync();
+				if(f.isSuccess()) {
+					System.out.println("******************************Netty启动成功******************************");
+				}
+				// 监听服务器关闭监听
+				f.channel().closeFuture().sync();
+			} catch (Exception e) {
+				e.printStackTrace();
+			} finally {
+				bossGroup.shutdownGracefully();
+				workerGroup.shutdownGracefully();
+			}
+		}
+	}
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServerController.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServerController.java
new file mode 100644
index 0000000..8720df9
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/NettyServerController.java
@@ -0,0 +1,399 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import cn.mb.cloud.gateway.util.RedisUtil;
+import cn.mb.cloud.gateway.util.SinataUtil;
+import cn.mb.cloud.gateway.util.SpringUtil;
+import com.alibaba.csp.sentinel.util.StringUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelHandlerContext;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.util.LinkedMultiValueMap;
+import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Timer;
+import java.util.TimerTask;
+
+
+/**
+ * Netty业务逻辑层
+ * @author sinata
+ * @createDate 2016年6月3日
+ * @version 1.0
+ */
+public class NettyServerController {
+	
+	public static Hashtable<String, Hashtable<ChannelHandlerContext, String>> map = new Hashtable<String, Hashtable<ChannelHandlerContext,String>>();
+
+	public static Hashtable<String,String> table;
+
+	private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class);
+
+
+	private RestTemplate internalRestTemplate = SpringUtil.getObject(RestTemplate.class);
+
+
+
+
+	static{
+		if(table == null){
+			table = new Hashtable<>();
+		}
+	}
+	
+	public static boolean isdebug = false;
+	public static int i = 0;
+
+
+	/**
+	 * 判断客户端要执行什么操作
+	 * 
+	 * @param ctx
+	 * @param msg
+	 * @author TaoNingBo
+	 */
+	public void JudgeOperation(ChannelHandlerContext ctx, Object msg) {
+        try {
+        	// ByteBuf转String
+        	ByteBuf byteBuf = (ByteBuf) msg;
+
+        	byte[] req = new byte[byteBuf.readableBytes()];
+        	byteBuf.readBytes(req);
+        	msg = new String(req, "UTF-8");
+        	// 验证即时通讯命令是否正确有效
+        	if(SinataUtil.isEmpty(msg)) {
+        		return;
+        	}
+        	String msgStr = msg.toString();
+			if(msgStr.indexOf("{") == -1 || msgStr.indexOf("}") == -1 || msgStr.indexOf("code") == -1 || msgStr.indexOf("msg") == -1 || msgStr.indexOf("data") == -1 || msgStr.indexOf("method") == -1) {
+				return;
+			}
+			if(isdebug) {
+//				System.out.println("<<<--receive-->>>" + msg);
+			}
+			
+			// 获取socket信息,保存相应的socket
+			JSONObject jsonMsg = JSONObject.parseObject(msg.toString());
+			int code = jsonMsg.getInteger("code");
+			String message = jsonMsg.getString("msg");
+			String method = jsonMsg.getString("method");
+			if(code != 200 || !message.equals("SUCCESS")) {
+				return;
+			}
+			JSONObject jsonCon = JSONObject.parseObject(jsonMsg.get("data").toString());
+
+			if(null != ctx && ctx.channel().isActive()){
+				jsonMsg.put("method", Method.pong);
+				sendMsgToClient(ctx, jsonMsg.toJSONString());
+			}
+
+			//心跳
+			if(method.equals(Method.ping)) {
+				Integer type = jsonCon.getInteger("type");
+				String token = jsonCon.getString("token");
+                String userId1 = jsonCon.getString("userId");
+				String device = jsonCon.getString("device");
+				String version = jsonCon.getString("version");
+                if(StringUtil.isNotEmpty(userId1)){
+
+                    //判断用户或者司机长连接
+                    if(type==1){
+                        //确保账号在单个设备上登录
+                        if(StringUtil.isNotEmpty(token)){
+                            String token_ = redisUtil.getValue("USER_APP_"+ userId1);//获取缓存中最新的数据
+                            if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向其他设备发送数据
+                                JSONObject msg_ = new JSONObject();
+                                msg_.put("code", 200);
+                                msg_.put("msg", "SUCCESS");
+                                msg_.put("method", "OFFLINE");
+                                msg_.put("data", new Object());
+								this.sendMsgToClient(ctx, msg_.toJSONString());//给当前通道发送消息
+                                TimerTask timerTask = new TimerTask() {
+                                    @Override
+                                    public void run() {
+                                        NettyChannelMap.remove_(ctx);
+										NettyChannelMap.remove(ctx);
+                                    }
+                                };
+                                Timer timer = new Timer();
+                                timer.schedule(timerTask, 3000);
+                                timer.cancel();
+                            }else{
+								NettyChannelMap.update_(token.substring(0, 23), ctx);
+								NettyChannelMap.update("USER" + userId1, ctx);
+								String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+								ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes()));
+							}
+                            if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况
+                                redisUtil.setStrValue("USER_APP_" + userId1, token);
+                            }
+                        }
+
+                    }else{
+						//添加司机在线
+						HttpHeaders headers = new HttpHeaders();
+						// 以表单的方式提交
+						headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+						//将请求头部和参数合成一个请求
+						MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+						params.add("driverId", userId1);
+						params.add("device", (null != device && device.equals("carDevice")) ? "2" : "1");
+						params.add("version", version);
+						HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
+						String w = internalRestTemplate.postForObject("http://driver-server/base/driverOnline/addDriverOnline",requestEntity , String.class);
+						JSONObject jsonObject = JSON.parseObject(w, JSONObject.class);
+						if(jsonObject.getIntValue("code") != 200){
+							System.err.println("调用driver-server添加司机在线数据出错了");
+						}
+
+						//TODO 存储最后一次上传的时间(用于保证车载端断电后1小时自动下班)
+						if(StringUtil.isNotEmpty(device) && device.equals("carDevice")){
+							redisUtil.setStrValue("DEVICE_" + userId1, String.valueOf(System.currentTimeMillis()));
+
+							String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据
+							if(StringUtil.isNotEmpty(token_) && !token_.equals(token)){
+								//如果是车载端登录,则将其它端都强迫下线
+								JSONObject msg_ = new JSONObject();
+								msg_.put("code", 200);
+								msg_.put("msg", "SUCCESS");
+								msg_.put("method", "OFFLINE");
+								msg_.put("data", new Object());
+								this.sendMsgToClient(ctx, msg_.toJSONString());//给当前通道发送消息
+								TimerTask timerTask = new TimerTask() {
+									@Override
+									public void run() {
+										NettyChannelMap.remove_(ctx);
+										NettyChannelMap.remove(ctx);
+									}
+								};
+								Timer timer = new Timer();
+								timer.schedule(timerTask, 3000);
+								timer.cancel();
+							}else{
+//								System.err.println("开始存储司机通道" + userId1);
+								NettyChannelMap.update("DRIVER" + userId1, ctx);
+								NettyChannelMap.update_(token.substring(0, 23), ctx);
+								String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+								ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes()));
+							}
+							if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况
+								redisUtil.setStrValue("DRIVER_" + userId1, token);
+							}
+						}
+
+
+                        //确保账号在单个设备上登录
+						String value = redisUtil.getValue("DEVICE_" + userId1);
+						if(StringUtil.isNotEmpty(token) && StringUtil.isEmpty(device) && StringUtil.isEmpty(value)){//APP端登录的操作
+                            String token_ = redisUtil.getValue("DRIVER_" + userId1);//缓存中拿最新数据
+                            if(StringUtil.isNotEmpty(token_) && !token.equals(token_)){//不在同一设备上登录,向当前设备发送数据
+                                JSONObject msg_ = new JSONObject();
+                                msg_.put("code", 200);
+                                msg_.put("msg", "SUCCESS");
+                                msg_.put("method", "OFFLINE");
+                                msg_.put("data", new Object());
+								this.sendMsgToClient(ctx, msg_.toJSONString());//给当前通道发送消息
+                                TimerTask timerTask = new TimerTask() {
+                                    @Override
+                                    public void run() {
+                                        NettyChannelMap.remove_(ctx);
+										NettyChannelMap.remove(ctx);
+                                    }
+                                };
+                                Timer timer = new Timer();
+                                timer.schedule(timerTask, 3000);
+                                timer.cancel();
+                            }else{
+//								System.err.println("开始存储司机通道" + userId1);
+								NettyChannelMap.update("DRIVER" + userId1, ctx);
+								NettyChannelMap.update_(token.substring(0, 23), ctx);
+								String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+								ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes()));
+							}
+                            if(StringUtil.isEmpty(token_)){//确保登录的时候存储token失败的情况
+                                redisUtil.setStrValue("DRIVER_" + userId1, token);
+                            }
+                        }
+
+
+                        //存储通讯通道
+                        if(null != ctx && ctx.channel().isActive()){
+//                            System.err.println("开始存储司机通道" + userId1);
+                            NettyChannelMap.update("DRIVER" + userId1, ctx);
+                            String s = NettyMsg.setMsg(Method.ok, new HashMap<String, Object>());
+                            ctx.writeAndFlush(Unpooled.copiedBuffer((s).getBytes()));
+                        }
+                    }
+                }
+			}
+			//司机上传位置
+			if(method.equals(Method.location)){
+				Integer driverId = jsonCon.getInteger("driverId");
+				Integer orderId = jsonCon.getInteger("orderId");
+				Integer orderType = jsonCon.getInteger("orderType");
+				Double lon = jsonCon.getDouble("lon");
+				Double lat = jsonCon.getDouble("lat");
+				Double computeAzimuth = jsonCon.getDouble("computeAzimuth");
+				Double altitude = jsonCon.getDouble("altitude");
+				if(SinataUtil.isNotEmpty(driverId)){
+					if(null !=  lon && 0 != lon && null !=  lat && 0 != lat){
+						if(null != orderId && 0 != driverId && null != orderType && 0 != orderType){//开始存入数据库
+							HttpHeaders headers = new HttpHeaders();
+							// 以表单的方式提交
+							headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
+							//将请求头部和参数合成一个请求
+							MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
+							params.add("orderType", String.valueOf(orderType));
+							params.add("orderId", String.valueOf(orderId));
+							params.add("driverId", String.valueOf(driverId));
+							params.add("lon", String.valueOf(lon));
+							params.add("lat", String.valueOf(lat));
+							params.add("directionAngle", String.valueOf(computeAzimuth));
+							params.add("altitude", String.valueOf(altitude));
+							HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
+							String s = internalRestTemplate.postForObject("http://driver-server/base/savePosition",requestEntity , String.class);
+							JSONObject jsonObject = JSON.parseObject(s, JSONObject.class);
+							if(jsonObject.getIntValue("code") != 200){
+								System.err.println("调用driver-server存储位置数据出错了");
+							}
+						}
+                        redisUtil.setStrValue("DRIVER" + driverId, lon + "," + lat, 300);//实时位置存入redis中
+					}else{
+						NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString());
+					}
+				}else{
+					NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString());
+				}
+			}
+			
+		} catch (Exception e) {
+			if(isdebug) {
+				NettyServerController.sendMsgToClient(ctx, "__error__" + msg.toString());
+			}
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * 向客户端发送消息
+	 * 
+	 * @param ctx
+	 * @param msg
+	 * @author TaoNingBo
+	 */
+	public static void sendMsgToClient(ChannelHandlerContext ctx, String msg) {
+		if (ctx != null && ctx.channel().isActive()) {
+			ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes());
+			ChannelFuture sync;
+			try {
+				sync = ctx.writeAndFlush(buffer).sync();
+				if(!sync.isSuccess()){//如果推送失败则继续推送10次
+					boolean b = true;
+					for (int i = 0; i < 10; i++) {
+						ctx.wait(3000);
+						sync = ctx.writeAndFlush(buffer).sync();
+						if(sync.isSuccess()){
+							b = false;
+							break;
+						}
+						System.err.println("推送不成功,将继续推送"+msg);
+					}
+					if(b){
+						NettyChannelMap.remove(ctx);
+					}
+				}
+			} catch (Exception e) {
+				System.err.println("推送发生异常,记录:"+msg);
+				NettyChannelMap.remove(ctx);
+			}
+			if(isdebug) {
+				System.err.println("<<<--send-->>>" + msg) ;
+			}
+		}else{
+			System.err.println("推送失败,长连接不存在");
+			NettyChannelMap.remove(ctx);
+		}
+	}
+
+//	**链接断开 将推送消息记录
+	public static void sendMsgToClient(String cacheType, Integer id,String msg) {
+		ChannelHandlerContext ctx = NettyChannelMap.getData(cacheType + id);
+		if (ctx != null) {
+			ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes());
+			ChannelFuture sync;
+			try {
+				sync = ctx.writeAndFlush(buffer).sync(); 
+//				System.out.println("推送状态"+sync.isSuccess());
+				if(!sync.isSuccess()){
+					for (int i = 0; i < 10; i++) {
+						sync = ctx.writeAndFlush(buffer).sync(); 
+						if(!sync.isSuccess()){
+							sync = ctx.writeAndFlush(buffer).sync(); 
+							System.err.println("推送不成功,将继续推送"+msg);
+							if(i == 9){
+								table.put(cacheType+id, msg);
+
+								ctx.close();
+								System.err.println("推送发生异常,记录:"+msg);
+							}
+						}else{
+							break;
+						}
+					}
+				}
+			} catch (Exception e) {
+				table.put(cacheType+id, msg);
+				System.err.println("推送发生异常,记录:"+msg);
+			}
+			if(isdebug) {
+//				System.out.println("<<<--send-->>>" + msg);
+			}
+		}else{
+			table.put(cacheType+id, msg);
+			System.err.println("链接断开,记录:id="+cacheType+id+",消息:"+msg);
+		}
+	}
+	
+	/**
+	 * 记录推送不成功消息,并在心跳连接续推
+	 * @param token
+	 */
+	public static void resendMsg(String token){
+		String msg = table.get(token);
+		ChannelHandlerContext ctx = NettyChannelMap.getData(token);
+		if(SinataUtil.isNotEmpty(msg) && ctx != null && ctx.channel().isActive()){
+			ByteBuf buffer = Unpooled.copiedBuffer((msg).getBytes());
+			ChannelFuture sync;
+			try {
+				sync = ctx.writeAndFlush(buffer).sync(); 
+				System.err.println("重发异常推送状态"+sync.isSuccess()+",位置:"+token+",消息内容:"+msg);
+				if(!sync.isSuccess()){
+					i++;
+					if(i == 10){
+						i =0;
+						ctx.close();
+						return;
+					}
+					System.err.println("重发异常推送不成功,将继续推送"+msg);
+					resendMsg(token);
+				}else{
+					i=0;
+				}
+				table.remove(token);
+			} catch (Exception e) {
+				resendMsg(token);
+				System.err.println("重发推送发生异常,记录:"+msg);
+			}
+		}
+	}
+
+
+}
diff --git a/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/ServerInit.java b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/ServerInit.java
new file mode 100644
index 0000000..2b131fa
--- /dev/null
+++ b/cloud-server-gateway/src/main/java/cn/mb/cloud/gateway/util/echo/ServerInit.java
@@ -0,0 +1,25 @@
+package cn.mb.cloud.gateway.util.echo;
+
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.handler.codec.string.StringDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+
+import java.nio.charset.Charset;
+
+public class ServerInit extends ChannelInitializer<SocketChannel> {
+
+	private DiscardServerHandler discardServerHandler = new DiscardServerHandler();
+
+	@Override
+	protected void initChannel(SocketChannel ch) throws Exception {
+		ChannelPipeline pipeline = ch.pipeline();
+        pipeline.addLast(new StringDecoder(Charset.forName("utf-8")));
+        pipeline.addLast(new StringEncoder(Charset.forName("utf-8")));
+        // 心跳监测机制
+//	        pipeline.addLast(new IdleStateHandler(5,7,10, TimeUnit.SECONDS));
+        pipeline.addLast(discardServerHandler);
+	}
+
+}
diff --git a/cloud-server-management/mb-cloud-management.iml b/cloud-server-management/mb-cloud-management.iml
deleted file mode 100644
index 1daccae..0000000
--- a/cloud-server-management/mb-cloud-management.iml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module version="4">
-  <component name="FacetManager">
-    <facet type="Spring" name="Spring">
-      <configuration />
-    </facet>
-  </component>
-</module>
\ No newline at end of file
diff --git a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_two.html b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_two.html
index 56fd499..7c62805 100644
--- a/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_two.html
+++ b/cloud-server-management/src/main/webapp/WEB-INF/view/system/tGoods/TGoods_detail_two.html
@@ -65,7 +65,7 @@
                     <label class="col-sm-3 control-label">所属门店:</label>
                     <div class="col-sm-9">
                         <select class="form-control" id="storeId" name="storeId">
-                            <option value="">${item.name}</option>
+                            <option value="">${shopName}</option>
                         </select>
                     </div>
                 </div>
@@ -74,7 +74,7 @@
                     <label class="col-sm-3 control-label">课包类型:</label>
                     <div class="col-sm-9">
                         <select class="form-control" id="coursePackageTypeId" name="pCode" onchange="TGoodsInfoDlg.packageChange(this)">
-                            <option value="">${shopName}</option>
+                            <option value="">${typeName}</option>
                         </select>
                     </div>
                 </div>
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
index d701c3b..9d8a468 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/SiteController.java
@@ -1,13 +1,10 @@
 package com.dsh.other.controller;
 
-import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.dsh.other.entity.Site;
 import com.dsh.other.entity.SiteBooking;
 import com.dsh.other.entity.SiteType;
-import com.dsh.other.entity.TSite;
 import com.dsh.other.feignclient.account.CityManagerClient;
-import com.dsh.other.feignclient.account.model.CityManager;
 import com.dsh.other.feignclient.activity.UserCouponClient;
 import com.dsh.other.feignclient.activity.model.QueryUserCouponByIdAndUserId;
 import com.dsh.other.feignclient.activity.model.UserCoupon;
@@ -16,7 +13,6 @@
 import com.dsh.other.feignclient.model.SiteVo;
 import com.dsh.other.model.*;
 import com.dsh.other.model.dto.siteDto.TSiteDTO;
-import com.dsh.other.model.vo.questionVo.QuestionChangeStateVO;
 import com.dsh.other.model.vo.siteVo.ExpireSiteSearchVO;
 import com.dsh.other.model.vo.siteVo.SiteSearchVO;
 import com.dsh.other.service.ISiteBookingService;
@@ -28,8 +24,8 @@
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
@@ -143,7 +139,6 @@
             return ResultUtil.runErr();
         }
     }
-
 
 
 
@@ -324,6 +319,8 @@
             if(null == uid){
                 return ResultUtil.tokenErr();
             }
+
+
             return siteService.cancelMySite(uid, id);
         }catch (Exception e){
             e.printStackTrace();
diff --git a/cloud-server-other/src/main/java/com/dsh/other/controller/StoreController.java b/cloud-server-other/src/main/java/com/dsh/other/controller/StoreController.java
index f1c96eb..9dc6cfa 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/controller/StoreController.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/controller/StoreController.java
@@ -246,7 +246,7 @@
      */
     @ResponseBody
     @PostMapping("/store/queryStoreListByName")
-    public List<Store> queryStoreListByName(@RequestParam("name") String name){
+    public List<Store> queryStoreListByName(@RequestBody String name){
         try {
             List<Store> stores = storeService.list(new QueryWrapper<Store>().eq("state", 1).like("name", name));
             return stores;
diff --git a/cloud-server-other/src/main/java/com/dsh/other/entity/Site.java b/cloud-server-other/src/main/java/com/dsh/other/entity/Site.java
index 877477b..c85c10f 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/entity/Site.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/entity/Site.java
@@ -108,5 +108,15 @@
     @TableField("insertTime")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
     private Date insertTime;
+    @TableField("imgs")
+    private String imgs;
+    @TableField("introduce")
+    private String introduce;
+    @TableField("是否半场 1是 2否")
+    private Integer ishalf;
+    @TableField("场地名称 多个逗号分割")
+    private String nextName;
+    @TableField("半场名称 多个逗号分割")
+    private String halfName;
 
 }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java b/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java
index 3c977b1..91a06f9 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/entity/SiteBooking.java
@@ -155,4 +155,12 @@
      */
     @TableField("insertTime")
     private Date insertTime;
+    @TableField("nextName")
+    private String nextName;
+    @TableField("isHalf")
+    private Integer isHalf;
+    @TableField("halfName")
+    private String halfName;
+    @TableField("goType")
+    private Integer goType;
 }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/model/QuerySiteInfoVo.java b/cloud-server-other/src/main/java/com/dsh/other/model/QuerySiteInfoVo.java
index 58b3875..0826ae5 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/model/QuerySiteInfoVo.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/model/QuerySiteInfoVo.java
@@ -4,6 +4,8 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.util.List;
+
 /**
  * @author zhibing.pu
  * @date 2023/7/17 11:49
@@ -35,4 +37,15 @@
     private Double cashPrice;
     @ApiModelProperty("玩湃币价格(x/半小时)")
     private Integer playPaiCoin;
+    @ApiModelProperty("图片 逗号拼接")
+    private String imgs;
+    @ApiModelProperty("多场地名称")
+    private List<String> nextName;
+    @ApiModelProperty("半场名称")
+    private List<String> halfName;
+    @ApiModelProperty("是否半场 1是 2否")
+    private Integer ishalf;
+    @ApiModelProperty("场地说明")
+    private String introduce;
+
 }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/model/ReservationSite.java b/cloud-server-other/src/main/java/com/dsh/other/model/ReservationSite.java
index fe90108..2e491b2 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/model/ReservationSite.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/model/ReservationSite.java
@@ -23,4 +23,10 @@
     private String phone;
     @ApiModelProperty(value = "支付方式(1=微信,2=支付宝,3=玩湃比)", dataType = "int", required = true)
     private Integer payType;
+    @ApiModelProperty(value = "场地名称", dataType = "String", required = false)
+    private String nextName;
+    @ApiModelProperty(value = "是否半场 1是 2否",required = false)
+    private Integer isHalf;
+    @ApiModelProperty(value = "半场名称",required = false)
+    private String halfName;
 }
diff --git a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
index 98459ce..e1de1aa 100644
--- a/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
+++ b/cloud-server-other/src/main/java/com/dsh/other/service/impl/SiteServiceImpl.java
@@ -1,5 +1,6 @@
 package com.dsh.other.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -109,7 +110,24 @@
         querySiteInfoVo.setStoreLon(store.getLon());
         querySiteInfoVo.setStoreLat(store.getLat());
         querySiteInfoVo.setStorePhone(store.getPhone());
+        querySiteInfoVo.setImgs(site.getImgs());
         querySiteInfoVo.setDistance(0D);
+        querySiteInfoVo.setIntroduce(site.getIntroduce());
+        ArrayList<String> nextName = new ArrayList<>();
+        ArrayList<String> halfName = new ArrayList<>();
+        String nextName1 = site.getNextName();
+        String halfName1 = site.getHalfName();
+
+        String[] split = nextName1.split(",");
+        for (String s : split) {
+            nextName.add(s);
+        }
+        String[] split1 = halfName1.split(",");
+        for (String s : split1) {
+            halfName.add(s);
+        }
+        querySiteInfoVo.setHalfName(halfName);
+        querySiteInfoVo.setNextName(nextName);
         if(ToolUtil.isNotEmpty(lon) && ToolUtil.isNotEmpty(lat)){
             Map<String, Double> distance = GeodesyUtil.getDistance(lon + "," + lat, store.getLon() + "," + store.getLat());
             double wgs84 = new BigDecimal(distance.get("WGS84")).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_EVEN).doubleValue();
@@ -269,6 +287,11 @@
         siteBooking.setStatus(0);
         siteBooking.setState(1);
         siteBooking.setInsertTime(new Date());
+
+        // 2.0
+        siteBooking.setNextName(reservationSite.getNextName());
+        siteBooking.setIsHalf(reservationSite.getIsHalf());
+        siteBooking.setHalfName(reservationSite.getHalfName());
         siteBookingService.save(siteBooking);
 
         if(reservationSite.getPayType() == 1){//微信支付
@@ -459,6 +482,12 @@
     @Override
     public ResultUtil cancelMySite(Integer uid, Integer id) throws Exception {
         SiteBooking siteBooking = siteBookingService.getById(id);
+
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
+        Date startTime = siteBooking.getStartTime();
+        if(format.format(new Date()).equals(format.format(startTime))){
+            return ResultUtil.error("预约当天,不能取消");
+        }
         if(siteBooking.getStatus() == 0){
             return ResultUtil.error("请先进行支付");
         }

--
Gitblit v1.7.1