刘俊驰 8 ماه پیش
والد
کامیت
d713a4b212
20فایلهای تغییر یافته به همراه645 افزوده شده و 185 حذف شده
  1. 31 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EDiscountType.java
  2. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserOrderDetail.java
  3. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java
  4. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponInfoService.java
  5. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  6. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  7. 17 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java
  8. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonPurchaseRecordService.java
  9. 0 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java
  10. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponInfoServiceImp.java
  11. 34 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  12. 98 63
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  13. 23 28
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java
  14. 3 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  15. 64 22
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  16. 283 44
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  17. 27 13
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonPurchaseRecordServiceImpl.java
  18. 10 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java
  19. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/coupon/CouponOrderWrapper.java
  20. 2 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponInfoMapper.xml

+ 31 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EDiscountType.java

@@ -0,0 +1,31 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+public enum EDiscountType implements BaseEnum<String, EDiscountType> {
+
+    COUPON("优惠券"),
+    ACTIVATY("活动"),
+    DISCOUNT("畅学卡"),
+    ;
+
+    @EnumValue
+    private String code;
+
+    private String desc;
+
+    EDiscountType(String desc) {
+        this.code = this.name();
+        this.desc = desc;
+    }
+
+    @Override
+    public String getCode() {
+        return name();
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserOrderDetail.java

@@ -80,6 +80,10 @@ public class UserOrderDetail implements Serializable {
     @TableField(value = "account_config_")
     private String accountConfig;
 
+    @ApiModelProperty("优惠json")
+    @TableField(value = "discount_json_")
+    private String discountJson;
+
     @ApiModelProperty("下单时间 ")
 	@TableField(value = "create_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java

@@ -20,6 +20,7 @@ public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
     TENANT_ALBUM("机构专辑"),
     PIANO_ROOM("琴房时长"),
     ACTI_REGIST("活动报名"),
+    VIP_COURSE("VIP定制课购买"),
     DISCOUNT("畅学卡")
     ;
 

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CouponInfoService.java

@@ -83,4 +83,12 @@ public interface CouponInfoService extends IService<CouponInfo> {
      * @return
      */
     int updateStock(Long couponId, int size, InOrOutEnum inOrOut);
+
+    /**
+     * 使用优惠券
+     *
+     * @param couponIssueId 优惠券发放ID
+     * @param orderNo 订单编号
+     */
+    void useCoupon(Long couponIssueId, String orderNo);
 }

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java

@@ -360,6 +360,13 @@ public interface CourseGroupService extends IService<CourseGroup> {
      */
     void buyLiveCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 
+    /**
+     *
+     * 直播课购买后数据写入
+     *
+     */
+    void buyLiveCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
     //老师端-我的课程组
     IPage<CourseGroupWrapper.TeacherCourseGroupDto> myCourseGroup(IPage<CourseGroupWrapper.TeacherCourseGroupDto> page,
                                                                   CourseGroupWrapper.TeacherCourseGroupQuery query);

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java

@@ -295,5 +295,11 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
      *
      */
     void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
+    /**
+     * 购买陪练课后
+     *
+     */
+    void buyPracticeCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }
 

+ 17 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderPayReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
@@ -14,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
 import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.EDiscountType;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -197,7 +199,7 @@ public interface UserOrderService extends IService<UserOrder> {
      * 记录活动参与
      *
      */
-    void saveActivityRecord(UserOrderDetailVo orderDetailVo);
+    void saveActivityRecord(UserOrderVo orderDetailVo);
 
     Date getAccountPeriodTime(UserOrderDetailVo orderDetailVo);
 
@@ -234,4 +236,18 @@ public interface UserOrderService extends IService<UserOrder> {
     void testOrderSuccess(String orderNo);
 
     Map<String,UserOrder> getMapByOrderNos(List<String> orderNoList);
+
+    /**
+     * 设置订单详情 优惠信息
+     *
+     * @param discountType 优惠类型
+     * @param couponAmount 优惠金额
+     * @param discountJson 优惠信息
+     */
+    String discountJson(EDiscountType discountType, BigDecimal couponAmount, String discountJson);
+
+    /**
+     *  计算畅学卡优惠
+     */
+    void discountCard(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonPurchaseRecordService.java

@@ -31,4 +31,9 @@ public interface VideoLessonPurchaseRecordService extends IService<VideoLessonPu
     void buyVideoCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 
     void videoSend(Long teacherId, Long studentId, VideoLessonGroup lesson);
+
+    /**
+     * 购买视频课程后
+     */
+    void buyVideoCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

+ 0 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java

@@ -1047,9 +1047,6 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
         userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
 
-        // 存入缓存
-//        redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
-
     }
 
     /**

+ 17 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CouponInfoServiceImp.java

@@ -423,4 +423,21 @@ public class CouponInfoServiceImp extends ServiceImpl<CouponInfoMapper, CouponIn
     public int updateStock(Long couponId, int size, InOrOutEnum inOrOut) {
         return baseMapper.updateStock(couponId,size,inOrOut);
     }
+
+    @Override
+    @Transactional
+    public void useCoupon(Long couponIssueId, String orderNo) {
+        CouponIssue couponIssue = couponIssueMapper.selectById(couponIssueId);
+        if (couponIssue == null) {
+            throw new BizException("优惠券不存在");
+        }
+        if (couponIssue.getUseState() != CouponUseStateEnum.USABLE) {
+            throw new BizException("优惠券状态不可用");
+        }
+        couponIssue.setUseState(CouponUseStateEnum.USED);
+        couponIssue.setOrderNo(orderNo);
+        couponIssue.setUseTime(DateTime.now().getMillis());
+        couponIssueMapper.updateById(couponIssue);
+
+    }
 }

+ 34 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java

@@ -378,8 +378,6 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //校验购买的课程组每节课时间是否和自己的课时冲突
         batchCheckStudentCourseTime(studentId, courseList, CourseSchedule::getStartTime, CourseSchedule::getEndTime);
 
-        // TODO 写入学生购买课程记录 换到订单写入成功后写入
-        buyLiveCourseAfter(orderGoodsInfo.getOrderNo(), studentId, courseList, courseGroup,courseGroup.getCoursePrice());
 
 
         UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
@@ -399,10 +397,6 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
         userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(courseGroup.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
 
-        // 设置金额入账去向
-        // 存入缓存
-//        redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(courseGroup.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
-
     }
 
     @Override
@@ -419,6 +413,40 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     }
 
     /**
+     *
+     * 直播课购买后数据写入
+     *
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void buyLiveCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        Map<String, Object> param = WrapperUtil.toMap(orderGoodsInfo.getBizContent());
+        Long groupId = WrapperUtil.toLong(param, "groupId", "课程组id不能为空!");
+        //课程组信息
+        CourseGroup courseGroup = this.getOne(Wrappers.<CourseGroup>lambdaQuery()
+                .eq(CourseGroup::getId, groupId)
+                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+        );
+        if (Objects.isNull(courseGroup)) {
+            throw new BizException("课程组不存在!");
+        }
+        //只要不是销售中的课程组都提示无法购买
+        if (!courseGroup.getStatus().equals(CourseGroupEnum.APPLY.getCode())) {
+            throw new BizException("课程已结束销售!");
+        }
+        //课程信息
+        List<CourseSchedule> courseList = courseScheduleService.list(Wrappers.<CourseSchedule>lambdaQuery()
+                .eq(CourseSchedule::getCourseGroupId, groupId));
+        if (CollectionUtils.isEmpty(courseList)) {
+            throw new BizException("课程组课程不存在!");
+        }
+        // 写入学生购买课程记录 换到订单写入成功后写入
+        buyLiveCourseAfter(orderGoodsInfo.getOrderNo(), orderGoodsInfo.getUserId(), courseList,
+                courseGroup,orderGoodsInfo.getUserOrderDetail().getActualPrice());
+    }
+
+    /**
      * 取消课程组-下架课程组
      *
      * @param groupId 课程组

+ 98 - 63
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java

@@ -2492,20 +2492,106 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
 
     @Override
     public void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderGoodsInfo.getBizContent(), PracticeScheduleDto.class);
+        UserOrderDetail userOrderDetail = buyPracticeCourseTranV2(orderGoodsInfo);
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+        userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(scheduleDto.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
+    }
+
+
+    /**
+     * 购买陪练课后
+     *
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void buyPracticeCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
         ObjectMapper objectMapper = new ObjectMapper();
         PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderGoodsInfo.getBizContent(), PracticeScheduleDto.class);
+        List<CourseScheduleDate> dateList = scheduleDto.getClassTime();
+        Integer courseNum = scheduleDto.getCourseNum();//课程数
+
+        //校验课时数
+        if (dateList.size() != courseNum) {
+            throw new BizException("课程数与课时数不符");
+        }
 
         RLock lock = redissonClient.getLock("teacherId:" + scheduleDto.getTeacherId());
         try {
             if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
-                UserOrderDetail userOrderDetail = buyPracticeCourseTranV2(orderGoodsInfo);
-                orderGoodsInfo.setUserOrderDetail(userOrderDetail);
-                userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(scheduleDto.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
-                // 设置金额入账去向
-                // 存入缓存
-//                redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(scheduleDto.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
-
-                return;
+                //获取老师锁课缓存
+                RMap<Long, List<CourseTimeEntity>> map = courseGroupService.getExpireLiveLockTimeCache(scheduleDto.getTeacherId());
+                if (map.isExists()) {
+                    List<CourseTimeEntity> courseTimeCache = map.get(scheduleDto.getTeacherId());
+                    //校验缓存中的时间和当前自动生成的时间有没有重复
+                    dateList.forEach(item ->
+                    {
+                        if (checkCourseTime(courseTimeCache, CourseTimeEntity::getStartTime, CourseTimeEntity::getEndTime, item.getStartTime(), item.getEndTime())) {
+                            throw new BizException("与缓存中时间存在中途");
+                        }
+                    });
+                }
+
+                //批量检查老师课时在数据库是否重复
+                batchCheckTeacherCourseTime(scheduleDto.getTeacherId(), dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
+                //批量检查学生课时在数据库是否重复
+                batchCheckStudentCourseTime(orderGoodsInfo.getUserId(), dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
+
+
+                String orderNo = orderGoodsInfo.getOrderNo();
+                scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
+                scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
+                scheduleDto.setMixStudentNum(1);
+                scheduleDto.setStudentId(orderGoodsInfo.getUserId());
+
+                //写入course_group
+                baseMapper.addCourseGroup(scheduleDto);
+                Long groupId = scheduleDto.getGroupId();
+
+                //根据老师id获取默认配置声部原价
+                TeacherSubjectPrice teacherSubjectPrice = teacherSubjectPriceService.lambdaQuery()
+                        .eq(TeacherSubjectPrice::getTeacherId, scheduleDto.getTeacherId())
+                        .eq(TeacherSubjectPrice::getSubjectId, scheduleDto.getSubjectId())
+                        .eq(TeacherSubjectPrice::getCourseType, CourseScheduleEnum.PRACTICE.getCode()).one();
+                BigDecimal subjectPrice = teacherSubjectPrice.getSubjectPrice();
+
+                //每课实际价格
+                Map<Integer, BigDecimal> courseAveragePrice = WrapperUtil.getAveragePrice(scheduleDto.getCourseNum()
+                        , orderGoodsInfo.getUserOrderDetail().getActualPrice());
+
+                List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
+                for (int i = 0; i < classTime.size(); i++) {
+                    CourseScheduleDate date = classTime.get(i);
+                    CourseSchedule schedule = new CourseSchedule();
+                    schedule.setClassDate(date.getClassDate());
+                    schedule.setStartTime(date.getStartTime());
+                    schedule.setEndTime(date.getEndTime());
+                    schedule.setCourseGroupId(groupId);
+                    schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
+                    schedule.setClassNum(i + 1);
+                    schedule.setTeacherId(scheduleDto.getTeacherId());
+                    schedule.setLock(1);
+                    schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
+                    schedule.setCreatedBy(scheduleDto.getStudentId());
+                    //写入course_schedule
+                    baseMapper.insert(schedule);
+
+                    Long scheduleId = schedule.getId();
+                    CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
+                    payment.setUserId(scheduleDto.getStudentId());
+                    payment.setCourseId(scheduleId);
+                    payment.setCourseGroupId(groupId);
+                    payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
+                    payment.setOrderNo(orderNo);
+                    payment.setOriginalPrice(subjectPrice);//原价
+                    payment.setExpectPrice(subjectPrice);//预计价格
+                    payment.setActualPrice(courseAveragePrice.get(i + 1));//实际价格
+                    //写入course_schedule_student_payment
+                    courseScheduleStudentPaymentService.save(payment);
+                }
             }
         } catch (InterruptedException e) {
             throw new BizException("创建陪练课失败:{}", e.getMessage());
@@ -2514,7 +2600,6 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                 lock.unlock();
             }
         }
-        throw  new BizException("创建陪练课失败");
 
     }
 
@@ -2534,9 +2619,6 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (dateList.size() != courseNum) {
             throw new BizException("课程数与课时数不符");
         }
-        BigDecimal price = baseMapper.selectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());//老师设置声部价格
-        BigDecimal decimal = new BigDecimal(courseNum);//选购课程节数
-        BigDecimal multiply = price.multiply(decimal);//预计总价
 
         //获取老师锁课缓存
         RMap<Long, List<CourseTimeEntity>> map = courseGroupService.getExpireLiveLockTimeCache(scheduleDto.getTeacherId());
@@ -2556,69 +2638,22 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         //批量检查学生课时在数据库是否重复
         batchCheckStudentCourseTime(studentId, dateList, CourseScheduleDate::getStartTime, CourseScheduleDate::getEndTime);
 
-        // TODO 换在订单前处理
-        String orderNo = orderGoodsInfo.getOrderNo();
-        scheduleDto.setType(CourseScheduleEnum.PRACTICE.getCode());
-        scheduleDto.setStatus(CourseGroupEnum.NOT_SALE.getCode());
-        scheduleDto.setMixStudentNum(1);
-        scheduleDto.setStudentId(studentId);
-
-        //写入course_group
-        baseMapper.addCourseGroup(scheduleDto);
-        Long groupId = scheduleDto.getGroupId();
-
-        //根据老师id获取默认配置声部原价
-        TeacherSubjectPrice teacherSubjectPrice = teacherSubjectPriceService.lambdaQuery()
-                .eq(TeacherSubjectPrice::getTeacherId, scheduleDto.getTeacherId())
-                .eq(TeacherSubjectPrice::getSubjectId, scheduleDto.getSubjectId())
-                .eq(TeacherSubjectPrice::getCourseType, CourseScheduleEnum.PRACTICE.getCode()).one();
-        BigDecimal subjectPrice = teacherSubjectPrice.getSubjectPrice();
-
-        //每课实际价格
-        Map<Integer, BigDecimal> courseAveragePrice = WrapperUtil.getAveragePrice(scheduleDto.getCourseNum(), multiply);
 
-        List<CourseScheduleDate> classTime = scheduleDto.getClassTime();
-        for (int i = 0; i < classTime.size(); i++) {
-            CourseScheduleDate date = classTime.get(i);
-            CourseSchedule schedule = new CourseSchedule();
-            schedule.setClassDate(date.getClassDate());
-            schedule.setStartTime(date.getStartTime());
-            schedule.setEndTime(date.getEndTime());
-            schedule.setCourseGroupId(groupId);
-            schedule.setType(CourseScheduleEnum.PRACTICE.getCode());
-            schedule.setClassNum(i + 1);
-            schedule.setTeacherId(scheduleDto.getTeacherId());
-            schedule.setLock(1);
-            schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
-            schedule.setCreatedBy(scheduleDto.getStudentId());
-            //写入course_schedule
-            baseMapper.insert(schedule);
-
-            Long scheduleId = schedule.getId();
-            CourseScheduleStudentPayment payment = new CourseScheduleStudentPayment();
-            payment.setUserId(scheduleDto.getStudentId());
-            payment.setCourseId(scheduleId);
-            payment.setCourseGroupId(groupId);
-            payment.setCourseType(CourseScheduleEnum.PRACTICE.getCode());
-            payment.setOrderNo(orderNo);
-            payment.setOriginalPrice(subjectPrice);//原价
-            payment.setExpectPrice(subjectPrice);//预计价格
-            payment.setActualPrice(courseAveragePrice.get(i + 1));//实际价格
-            //写入course_schedule_student_payment
-            courseScheduleStudentPaymentService.save(payment);
-        }
+        BigDecimal price = baseMapper.selectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());//老师设置声部价格
+        BigDecimal decimal = new BigDecimal(courseNum);//选购课程节数
+        BigDecimal multiply = price.multiply(decimal);//预计总价
 
         UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
 
         userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
         userOrderDetail.setMerchId(scheduleDto.getTeacherId());
-        userOrderDetail.setBizId(groupId);
         userOrderDetail.setGoodNum(scheduleDto.getCourseNum());
         userOrderDetail.setOriginalPrice(multiply);
         userOrderDetail.setCouponAmount(BigDecimal.ZERO);
         userOrderDetail.setExpectPrice(multiply);
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice());
 
+
         log.info("buyPracticeCourse  return {}", userOrderDetail);
         return userOrderDetail;
     }

+ 23 - 28
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java

@@ -21,10 +21,13 @@ import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
+import com.yonge.cooleshow.common.enums.ActivityTypeEnum;
+import com.yonge.cooleshow.common.enums.EDiscountType;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.utils.date.DateUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,10 +37,8 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.math.RoundingMode;
+import java.util.*;
 import java.util.stream.Collectors;
 
 
@@ -294,17 +295,6 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         }
 
         BigDecimal couponAmount = BigDecimal.ZERO;
-        ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
-
-        if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
-            for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
-                if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(detail.getVipType().getCode())
-                        && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
-                    couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
-                    break;
-                }
-            }
-        }
 
         UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
 
@@ -315,7 +305,7 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
         userOrderDetail.setOriginalPrice(detail.getOriginalPrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
         userOrderDetail.setCouponAmount(couponAmount.multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
-        userOrderDetail.setExpectPrice(detail.getSalePrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
+        userOrderDetail.setExpectPrice(orderGoodsInfo.getGiftFlag()?BigDecimal.ZERO:detail.getSalePrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
 
@@ -476,15 +466,22 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         checkVip(detail, orderGoodsInfo.getVipEndDays(), orderGoodsInfo.getUserId(), orderGoodsInfo.getPaymentClient(), orderGoodsInfo.getGoodNum(), orderGoodsInfo.getBizPrice());
 
         BigDecimal couponAmount = BigDecimal.ZERO;
+        BigDecimal expectPrice = detail.getSalePrice();
         ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
 
-        if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
-            for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
-                if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(detail.getVipType().getCode())
-                    && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
-                    couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
-                    break;
+
+        if (activityPlanVo != null && activityPlanVo.getActivityState() == 1 ) {
+            if ( activityPlanVo.getActivityType() == ActivityTypeEnum.SHARE) {
+                for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
+                    if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(detail.getVipType().getCode())
+                            && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
+                        couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
+                        break;
+                    }
                 }
+            } else if (activityPlanVo.getActivityType() == ActivityTypeEnum.MEMBER && !orderGoodsInfo.getGiftFlag()) {
+                expectPrice = activityPlanVo.getRegistrationPrice();
+
             }
         }
 
@@ -497,8 +494,10 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
         userOrderDetail.setOriginalPrice(detail.getOriginalPrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
         userOrderDetail.setCouponAmount(couponAmount.multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
-        userOrderDetail.setExpectPrice(detail.getSalePrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
-        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
+        userOrderDetail.setExpectPrice(orderGoodsInfo.getGiftFlag()?BigDecimal.ZERO:expectPrice.subtract(couponAmount).multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice());
+        userOrderDetail.setDiscountJson(userOrderService.discountJson(EDiscountType.ACTIVATY,
+                couponAmount.multiply(new BigDecimal(orderGoodsInfo.getGoodNum())),userOrderDetail.getDiscountJson()));
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
 
         UserPaymentOrderWrapper.VipDays vipDays = new UserPaymentOrderWrapper.VipDays();
@@ -506,10 +505,6 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         userOrderDetail.setBizJson(JSON.toJSONString(vipDays));
         userOrderDetail.setAccountConfig( teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
 
-        // 设置金额入账去向
-        // 存入缓存
-//        redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
-
     }
 
     private void checkOrder(ClientEnum orderGoodsInfo, String orderType, Long userId) {

+ 3 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java

@@ -299,10 +299,9 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         BigDecimal serviceFee = new BigDecimal(musicSheetServiceFee).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
         //支付金额
         BigDecimal actualPrice = userPaymentOrder.getActualPrice();
-        BigDecimal expectPrice = userPaymentOrder.getExpectPrice();
 
         //服务费  原价的平台服务费 ,减去优惠券金额
-        BigDecimal serviceFeeAmount = expectPrice.multiply(serviceFee).subtract(userPaymentOrder.getCouponAmount()).setScale(2, RoundingMode.HALF_UP);
+        BigDecimal serviceFeeAmount = actualPrice.multiply(serviceFee).setScale(2, RoundingMode.HALF_UP);
         if (serviceFeeAmount.compareTo(BigDecimal.ZERO) < 0) {
             serviceFeeAmount = BigDecimal.ZERO;
         }
@@ -324,7 +323,7 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
             if (!musicSheet.getSourceType().getCode().equals(SourceTypeEnum.PLATFORM.getCode())) {
 
                 // 老师收入
-                BigDecimal teacherAmount = BigDecimal.ONE.subtract(serviceFee).multiply(expectPrice).setScale(2, RoundingMode.HALF_UP);
+                BigDecimal teacherAmount = BigDecimal.ONE.subtract(serviceFee).multiply(actualPrice).setScale(2, RoundingMode.HALF_UP);
 
                 // 判断分润给机构 还是给老师
                 // 机构ID = 0 老师设置了不分润
@@ -650,7 +649,7 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         BigDecimal liveServiceRate = new BigDecimal(sysConfigService.findConfigValue(SysConfigConstant.VIDEO_LESSON_SERVICE_FEE))
                 .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
         //支付金额
-        BigDecimal expectPrice = userPaymentOrder.getExpectPrice();
+        BigDecimal expectPrice = userPaymentOrder.getActualPrice();
         //服务费
         serviceFeeAmount = expectPrice.multiply(liveServiceRate).setScale(2, RoundingMode.HALF_UP);
         //老师入账金额

+ 64 - 22
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java

@@ -31,10 +31,7 @@ import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.cooleshow.common.enums.ActivityResourceEnum;
-import com.yonge.cooleshow.common.enums.CacheNameEnum;
-import com.yonge.cooleshow.common.enums.EPaymentVersion;
-import com.yonge.cooleshow.common.enums.PostStatusEnum;
+import com.yonge.cooleshow.common.enums.*;
 import com.yonge.cooleshow.common.service.IdGeneratorService;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.result.BaseResult;
@@ -62,13 +59,7 @@ import javax.annotation.PostConstruct;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -1292,9 +1283,10 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(merchId)).delete();
             }
 
-            // 记录活动参与
-            saveActivityRecord(orderDetailVo);
         }
+
+        // 记录活动参与
+        this.saveActivityRecord(detail);
         //清除买家统计缓存
         if (ClientEnum.STUDENT.getCode().equals(detail.getPaymentClient())) {
             redissonClient.getBucket(CacheNameEnum.STUDENT_TOTAL.getRedisKey(detail.getUserId())).delete();
@@ -1309,20 +1301,25 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      */
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void saveActivityRecord(UserOrderDetailVo orderDetailVo) {
-        if (orderDetailVo.getActivityId() == null || orderDetailVo.getActivityId() == 0 || orderDetailVo.getRecomUserId() == null) {
+    public void saveActivityRecord(UserOrderVo userOrderVo) {
+        if (userOrderVo.getActivityId() == null || userOrderVo.getActivityId() == 0) {
             return;
         }
         ActivityRegistration activityRegistration = new ActivityRegistration();
-        activityRegistration.setActivityId(orderDetailVo.getActivityId());
-        activityRegistration.setOrderNo(orderDetailVo.getOrderNo());
-        activityRegistration.setSubOrderNo(orderDetailVo.getSubOrderNo());
-        activityRegistration.setUserId(orderDetailVo.getUserId());
+        activityRegistration.setActivityId(userOrderVo.getActivityId());
+        activityRegistration.setOrderNo(userOrderVo.getOrderNo());
+//        activityRegistration.setSubOrderNo(userOrderVo.getSubOrderNo());
+        activityRegistration.setUserId(userOrderVo.getUserId());
         activityRegistration.setCreateTime(new Date());
         activityRegistrationService.save(activityRegistration);
-        activityEvaluationRecordService.saveActivityRecord(orderDetailVo.getActivityId(), orderDetailVo.getUserId(),
-                                                           orderDetailVo.getRecomUserId(), ActivityResourceEnum.TEACHER);
-        activityUserRewardService.saveRewardRecord(orderDetailVo.getActivityId(),orderDetailVo.getRewardId(),orderDetailVo.getUserId());
+
+        ActivityPlan activityPlan = activityPlanService.getById(userOrderVo.getActivityId());
+
+        if (activityPlan != null && Lists.newArrayList(ActivityTypeEnum.SHARE,ActivityTypeEnum.EVALUATION).contains(activityPlan.getActivityType())) {
+            activityEvaluationRecordService.saveActivityRecord(userOrderVo.getActivityId(), userOrderVo.getUserId(),
+                    userOrderVo.getRecomUserId(), ActivityResourceEnum.TEACHER);
+            activityUserRewardService.saveRewardRecord(userOrderVo.getActivityId(), userOrderVo.getRewardId(), userOrderVo.getUserId());
+        }
     }
 
     /**
@@ -1568,4 +1565,49 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         return list.stream().collect(Collectors.toMap(UserOrder::getOrderNo, Function.identity()));
     }
 
+
+    /**
+     * 设置订单详情 优惠信息
+     *
+     * @param discountType 优惠类型
+     * @param couponAmount 优惠金额
+     * @param discountJson 优惠信息
+     */
+    @Override
+    public String discountJson(EDiscountType discountType, BigDecimal couponAmount, String discountJson) {
+        Map<String,BigDecimal> decimalMap = new HashMap<>();
+        if (!StringUtil.isEmpty(discountJson)) {
+            decimalMap = JSON.parseObject(discountJson, Map.class);
+        }
+        BigDecimal bigDecimal = decimalMap.get(discountType.getCode());
+        if (null == bigDecimal) {
+            bigDecimal = BigDecimal.ZERO;
+        }
+        decimalMap.put(discountType.getCode(), bigDecimal.add(couponAmount));
+        return JSON.toJSONString(decimalMap);
+
+    }
+
+    @Override
+    public void discountCard(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        // 计算畅学卡优惠
+        if (orderGoodsInfo.getDiscountFlag() && orderGoodsInfo.getDiscountInfo() != null) {
+            MemberPriceSettings discountInfo = orderGoodsInfo.getDiscountInfo();
+            if (StringUtils.isNotBlank(discountInfo.getProductType())) {
+                List<String> list = Arrays.asList(discountInfo.getProductType().split(","));
+                // 满足折扣商品
+                if (list.contains(orderGoodsInfo.getGoodType().name())) {
+                    UserOrderDetail userOrderDetail = orderGoodsInfo.getUserOrderDetail();
+                    BigDecimal bigDecimal = userOrderDetail.getActualPrice().multiply(discountInfo.getDiscountRate()).setScale(2, RoundingMode.CEILING);
+                    BigDecimal couponPrice = userOrderDetail.getActualPrice().subtract(bigDecimal);
+                    userOrderDetail.setCouponAmount(userOrderDetail.getCouponAmount().add(couponPrice));
+                    userOrderDetail.setActualPrice(bigDecimal);
+                    userOrderDetail.setDiscountJson(userOrderService.discountJson(EDiscountType.DISCOUNT,couponPrice,userOrderDetail.getDiscountJson()));
+
+                }
+            }
+        }
+    }
+
 }

+ 283 - 44
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java

@@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
-import com.microsvc.toolkit.common.spring.SpringContextHolder;
 import com.microsvc.toolkit.common.tools.ThreadPool;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.middleware.payment.common.api.BasePaymentService;
@@ -15,10 +14,15 @@ import com.microsvc.toolkit.middleware.payment.common.api.entity.*;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.DivideBackStatus;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
 import com.microsvc.toolkit.middleware.payment.enums.EPaymentVendor;
+import com.yonge.cooleshow.biz.dal.dto.ActivityPlanRewardDto;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.mapper.CouponInfoMapper;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
 import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
@@ -105,6 +109,10 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
     private CouponInfoService couponInfoService;
 
     @Autowired
+    private CouponInfoMapper couponInfoMapper;
+
+
+    @Autowired
     private TenantAlbumService tenantAlbumService;
 
     @Autowired
@@ -153,13 +161,16 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
 
     // 订单完成后执行
     private static final Map<GoodTypeEnum, Consumer<UserOrderDetailVo>> paymentSuccess = Maps.newHashMap();
-
+    @Autowired
+    private StudentService studentService;
 
 
     @PostConstruct
     private void init() {
 
         /**********订单生成前 商品校验******************/
+
+        /* 订单前数据处理*/
         //vip开通缴费
         orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
         orderGoodsCreate.put(GoodTypeEnum.SVIP, memberPriceSettingsService::orderCreate);
@@ -190,6 +201,14 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         // 机构专辑
         orderSuccessAfter.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderAfterSheet);
 
+
+        //直播课程购买
+        orderSuccessAfter.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseAfter);
+        //陪练课购买
+        orderSuccessAfter.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourseAfter);
+        //视频课购买
+        orderSuccessAfter.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourseAfter);
+
         /**********订单完成后 数据处理******************/
         // 沿用以前的流程
 
@@ -363,9 +382,10 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             if (merchId != null && merchId != 0) {
                 redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(merchId)).delete();
             }
-            // 记录活动参与
-            userOrderService.saveActivityRecord(orderDetailVo);
         }
+
+        // 记录活动参与
+        userOrderService.saveActivityRecord(detail);
         //清除买家统计缓存
         if (ClientEnum.STUDENT.getCode().equals(detail.getPaymentClient())) {
             redissonClient.getBucket(CacheNameEnum.STUDENT_TOTAL.getRedisKey(detail.getUserId())).delete();
@@ -517,11 +537,18 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             .originalPrice(BigDecimal.ZERO);
 
         List<UserOrderDetail> orderDetails = new ArrayList<>();
-        // 订单优惠券信息
-        CouponOrderWrapper couponOrderWrapper = CouponOrderWrapper.builder()
-                .discountedPrices(0D)
-                .couponInfos(Lists.newArrayList())
-                .build();
+
+        // 检查是否有畅学卡
+        if (orderReq.getPaymentClient() == ClientEnum.STUDENT) {
+            // 检查畅学卡
+            checkDiscountCard(orderReq);
+        }
+
+        // 检查活动,如果是会员买赠活动,检查商品和赠送商品是否匹配
+        if (orderReq.getActivityId() !=null ) {
+            checkActivity(orderReq);
+        }
+
         // 购买商品信息
         for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
 
@@ -533,46 +560,22 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             item.setPaymentClient(orderReq.getPaymentClient());
             item.setRecomUserId(orderReq.getRecomUserId());
 
-
-            BigDecimal couponAmount = BigDecimal.ZERO;
             // 商品基本信息
             if (orderGoodsCreate.containsKey(item.getGoodType())) {
                 // 填充商品基础信息,校验参数合法以性
                 orderGoodsCreate.get(item.getGoodType()).accept(item);
                 UserOrderDetail userOrderDetail = item.getUserOrderDetail();
                 orderDetails.add(userOrderDetail);
-                couponAmount = userOrderDetail.getCouponAmount();
-                if (couponAmount == null) {
-                    couponAmount = BigDecimal.ZERO;
-                }
-                // 根据优惠券计算实际优惠金额
-                // 计算优惠券金额
-                {
-                    if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
-                        throw new BizException("暂不支持优惠券");
-//
-//                        couponOrderWrapper = couponInfoService.queryUserOrderCouponInfo(orderReq.getUserId(),
-//                                CouponInfoQuery.CouponOrderQuery.builder()
-//                                        .clientType(orderReq.getPaymentClient())
-//                                        .couponTypes(CouponCategoryEnum.getCategory(orderReq.getOrderType().getCode()))
-//                                        .useState(CouponUseStateEnum.USABLE)
-//                                        .timestamp(DateTime.now().getMillis())
-//                                        .amount(userOrderDetail.getExpectPrice().doubleValue())
-//                                        .build()
-//                                        .issueIds(orderReq.getCouponIds()));
-                    }
+            }
 
-                    // 优惠券优惠金额,暂时为0
-//                    couponAmount = couponAmount.add(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
+            // 计算畅学卡
+            userOrderService.discountCard(item);
 
-                    //不许使用优惠券
-                    if (couponAmount.compareTo(userOrderDetail.getExpectPrice()) > 0) {
-                        couponAmount = userOrderDetail.getExpectPrice();
-                    }
-                    userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount).setScale(2, RoundingMode.HALF_UP));
-                    userOrderDetail.setCouponAmount(couponAmount);
-                }
-            }
+        }
+
+        // 是否使用优惠券
+        if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
+            checkCoupon(orderReq);
 
         }
 
@@ -630,10 +633,9 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         }
 
         // 更新用户订单优惠券使用状态
-        if (CollectionUtils.isNotEmpty(couponOrderWrapper.getCouponInfos())) {
+        if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
 
-            couponOrderWrapper.useType(CouponCategoryEnum.goodTypeTo(orderReq.getOrderType().getCode()));
-            couponInfoService.updateUserOrderCouponInfo(couponOrderWrapper.orderNo(orderReq.getOrderNo()));
+            couponInfoService.useCoupon(Long.parseLong(orderReq.getCouponIds()),orderReq.getOrderNo());
         }
 
         String subject = orderDetails.stream()
@@ -669,6 +671,243 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         return build;
     }
 
+    private void checkDiscountCard(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
+
+        // 检查畅学卡
+        if (orderReq.getPaymentClient() == ClientEnum.STUDENT) {
+
+            Student student = studentService.getById(orderReq.getUserId());
+            if (student == null) {
+                throw new BizException("用户不存在");
+            }
+            boolean discountFlag = false;
+            if (student.getDiscountEndTime()!=null && student.getDiscountEndTime().after(new Date())) {
+                discountFlag = true;
+            }
+            // 没有畅学卡 ,循环商品检查是否有畅学卡
+            if (!discountFlag) {
+                for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
+                    if (item.getGoodType() == GoodTypeEnum.DISCOUNT) {
+                        discountFlag = true;
+                        break;
+                    }
+                }
+            }
+            MemberPriceSettings one = null;
+            if (discountFlag) {
+                one = memberPriceSettingsService.lambdaQuery()
+                        .eq(MemberPriceSettings::getVipType, EVipType.DISCOUNT)
+                        .eq(MemberPriceSettings::getStatus, true)
+                        .last("limit 1")
+                        .one();
+                if (one == null) {
+                    discountFlag  =false;
+                }
+
+            }
+
+            // 设置商品上的畅学卡标识
+            for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
+                item.setDiscountFlag(discountFlag);
+                item.setDiscountInfo(one);
+            }
+        }
+
+    }
+
+    private CouponOrderWrapper.CouponInfo checkCoupon(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
+        // 根据优惠券支持的商品类型,按比例分配优惠金额到各商品
+        // 查询用户订单优惠券信息
+        List<CouponOrderWrapper.CouponInfo> couponInfos = couponInfoMapper.selectUserOrderCouponInfo(orderReq.getUserId(),
+                CouponInfoQuery.CouponOrderQuery.builder()
+                    .clientType(orderReq.getPaymentClient())
+                    .useState(CouponUseStateEnum.USABLE)
+                    .timestamp(DateTime.now().getMillis())
+                    .build()
+                    .issueIds(orderReq.getCouponIds()));
+        if (CollectionUtils.isEmpty(couponInfos)) {
+            throw new BizException("优惠券不可用");
+        }
+
+
+        // 优惠券只支持使用一张
+        CouponOrderWrapper.CouponInfo couponInfo = couponInfos.get(0);
+        BigDecimal amount = BigDecimal.ZERO;
+        List<UserPaymentOrderWrapper.OrderGoodsInfo> goodsInfos = orderReq.getGoodsInfos();
+        Map<Integer,BigDecimal> couponAmountMap = new HashMap<>();
+        for (int i = 0; i < goodsInfos.size(); i++) {
+            UserPaymentOrderWrapper.OrderGoodsInfo goodsInfo = goodsInfos.get(i);
+
+            goodsInfo.setActivityId(orderReq.getActivityId());
+            /*
+
+UNIVERSAL("全场通用", "UNIVERSAL"),
+VIP("小酷Ai", "VIP"),
+SVIP("小酷Ai SVIP ", "SVIP"),
+PIANO("云酷琴房", "PIANO_ROOM"),
+MALL("商场购物券", "MALL"),
+MUSIC("单曲点播券", "MUSIC"),
+ALBUM("专辑优惠券", "ALBUM"),
+SPARRING("趣纠课购买券", "PRACTICE"),
+LIVE("直播课购买券", "LIVE"),
+VIDEO("视频课购买券", "VIDEO"),
+VIP_COURSE("VIP定制课购买券", "VIP_COURSE"),
+DISCOUNT("畅学卡","DISCOUNT"),
+
+    VIP("开通会员"),
+SVIP("开通会员 SVIP"),
+PRACTICE("陪练课购买"),
+LIVE("直播课购买"),
+VIDEO("视频课购买"),
+MUSIC("单曲点播"),
+ALBUM("专辑购买"),
+TENANT_ALBUM("机构专辑"),
+PIANO_ROOM("琴房时长"),
+ACTI_REGIST("活动报名"),
+DISCOUNT("畅学卡")
+             */
+            BigDecimal actualPrice = BigDecimal.ZERO;
+            switch (couponInfo.getCategory()) {
+                case UNIVERSAL:
+                    actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    break;
+                case VIP:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.VIP)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case SVIP:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.SVIP)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case PIANO:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.PIANO_ROOM)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case MUSIC:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.MUSIC)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case ALBUM:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.ALBUM)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case SPARRING:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.PRACTICE)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case LIVE:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.LIVE)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case VIDEO:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.VIDEO)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case VIP_COURSE:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.VIP_COURSE)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                case DISCOUNT:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.DISCOUNT)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if (actualPrice.compareTo(BigDecimal.ZERO)>0) {
+                amount = amount.add(actualPrice);
+                couponAmountMap.put(i,actualPrice);
+            }
+
+        }
+        // 判断满减
+        if (couponInfo.getUseLimit() != null && amount.compareTo(BigDecimal
+                .valueOf(couponInfo.getUseLimit()).setScale(2, BigDecimal.ROUND_HALF_UP)) < 0) {
+            throw new BizException("优惠券不可用");
+        }
+
+        // 根据商品金额比例分摊优惠金额
+        // 剩余金额
+        BigDecimal remainAmount = BigDecimal.ZERO;
+        for (Map.Entry<Integer, BigDecimal> entry : couponAmountMap.entrySet()) {
+            UserPaymentOrderWrapper.OrderGoodsInfo goodsInfo = goodsInfos.get(entry.getKey());
+            UserOrderDetail userOrderDetail = goodsInfo.getUserOrderDetail();
+            BigDecimal actualPrice = entry.getValue();
+            BigDecimal couponAmount = BigDecimal.valueOf(couponInfo.getDiscountPrice())
+                    .multiply(userOrderDetail.getActualPrice()).divide(amount, 2, RoundingMode.HALF_DOWN);
+            remainAmount = amount.subtract(couponAmount);
+            userOrderDetail.setCouponAmount(couponAmount.add(userOrderDetail.getCouponAmount()));
+
+            userOrderDetail.setDiscountJson(userOrderService.discountJson(EDiscountType.COUPON,
+                    couponAmount,userOrderDetail.getDiscountJson()));
+            userOrderDetail.setActualPrice(actualPrice.subtract(couponAmount).setScale(2, RoundingMode.HALF_UP));
+        }
+        if (remainAmount.compareTo(BigDecimal.ZERO) > 0) {
+            UserOrderDetail userOrderDetail = goodsInfos.get(0).getUserOrderDetail();
+            userOrderDetail.setActualPrice(userOrderDetail.getActualPrice().add(remainAmount));
+
+            userOrderDetail.setDiscountJson(userOrderService.discountJson(EDiscountType.COUPON,
+                    remainAmount,userOrderDetail.getDiscountJson()));
+        }
+        return couponInfo;
+
+    }
+
+    private void checkActivity(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
+        ActivityPlanVo activityPlan = activityPlanService.detail(orderReq.getActivityId());
+        if (activityPlan != null && activityPlan.getActivityState() == 1) {
+            if (ActivityTypeEnum.MEMBER == activityPlan.getActivityType()) {
+                // TODO 检查购买次数是否符合要求 待支付,支付中,支付完成的订单小于次数才可以继续购买
+
+                // 会员买赠活动 判断购买商品是否符合活动要求
+                Map<String, List<Long>> map = orderReq.getGoodsInfos().stream()
+                        .filter(o -> o.getGiftFlag() != null && !o.getGiftFlag())
+                        .collect(Collectors.groupingBy(o -> o.getGoodType().getCode(),
+                                Collectors.mapping(UserPaymentOrderWrapper.OrderGoodsInfo::getBizId, Collectors.toList())));
+                for (ActivityPlanRewardDto activityPlanRewardDto : activityPlan.getActivityRewardList()) {
+                    RewardTypeEnum rewardType = activityPlanRewardDto.getActivityReward().getRewardType();
+                    if (map.containsKey(rewardType.toString())) {
+                        List<Long> bizIds = map.get(rewardType.toString());
+                        if (!bizIds.contains(activityPlanRewardDto.getActivityReward().getVipCardId())) {
+                            throw new BizException("活动商品不符合要求");
+                        } else {
+                            bizIds.remove(activityPlanRewardDto.getActivityReward().getVipCardId());
+                        }
+                    }
+                }
+                // 购买的商品判断
+                map = orderReq.getGoodsInfos().stream()
+                        .filter(o -> o.getGiftFlag() == null || o.getGiftFlag())
+                        .collect(Collectors.groupingBy(o -> o.getGoodType().getCode(),
+                                Collectors.mapping(UserPaymentOrderWrapper.OrderGoodsInfo::getBizId, Collectors.toList())));
+                if (map.containsKey(GoodTypeEnum.VIP.name()) || map.containsKey(GoodTypeEnum.SVIP.name())) {
+                    MemberPriceSettings settings = memberPriceSettingsService.getById(activityPlan.getVipCardId());
+                    if (settings == null) {
+                        throw new BizException("活动商品不符合要求");
+                    }
+                    List<Long> list = map.get(settings.getVipType().name());
+                    if (list == null || !list.contains(settings.getId())) {
+                        throw new BizException("活动商品不符合要求");
+                    }
+                } else {
+                    throw new BizException("活动商品不符合要求");
+                }
+            }
+        } else {
+            throw new BizException("活动已结束");
+        }
+    }
+
     /**
      * 用户支付请求
      *

+ 27 - 13
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonPurchaseRecordServiceImpl.java

@@ -316,16 +316,6 @@ public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLesso
             throw new BizException("已购买过该课程,或存在该课程未完成订单");
         }
 
-        // TODO 购买记录放在订单生成后
-        purchaseRecord.setOrderNo(orderNo);
-        purchaseRecord.setStudentId(studentId);
-        purchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
-        purchaseRecord.setOriginalPrice(lessonGroup.getLessonPrice());//原价
-        purchaseRecord.setExpectPrice(lessonGroup.getLessonPrice());//预计价格
-        purchaseRecord.setPayMoney(lessonGroup.getLessonPrice());
-        videoLessonPurchaseRecordDao.insert(purchaseRecord);
-
-
 
         UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
 
@@ -343,9 +333,6 @@ public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLesso
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
 
         userOrderDetail.setAccountConfig(teacherService.teacherSettlementFrom(lessonGroup.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
-        // 设置金额入账去向
-        // 存入缓存
-//        redisCacheService.saveUserAccountConfig(orderGoodsInfo.getSubOrderNo(), teacherService.teacherSettlementFrom(lessonGroup.getTeacherId(),orderGoodsInfo.getRecomUserId()).jsonString());
 
     }
 
@@ -421,4 +408,31 @@ public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLesso
             e.printStackTrace();
         }
     }
+
+    /**
+     * 购买视频课程后
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void buyVideoCourseAfter(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        ObjectMapper objectMapper = new ObjectMapper();
+        VideoLessonPurchaseRecord purchaseRecord = objectMapper.convertValue(orderGoodsInfo.getBizContent(), VideoLessonPurchaseRecord.class);
+
+        //校验视频课信息
+        Long groupId = purchaseRecord.getVideoLessonGroupId();
+        VideoLessonGroup lessonGroup = videoLessonGroupDao.selectById(groupId);
+        if (lessonGroup == null) {
+            throw new BizException("课程组不存在!");
+        }
+        // TODO 购买记录放在订单生成后
+        purchaseRecord.setOrderNo(orderGoodsInfo.getOrderNo());
+        purchaseRecord.setStudentId(orderGoodsInfo.getUserId());
+        purchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY.getCode());
+        purchaseRecord.setOriginalPrice(lessonGroup.getLessonPrice());//原价
+        purchaseRecord.setExpectPrice(lessonGroup.getLessonPrice());//预计价格
+        purchaseRecord.setPayMoney(orderGoodsInfo.getUserOrderDetail().getActualPrice());
+        videoLessonPurchaseRecordDao.insert(purchaseRecord);
+
+    }
 }

+ 10 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.biz.dal.wrapper;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
@@ -862,6 +863,15 @@ public class UserPaymentOrderWrapper {
         @ApiModelProperty(value = "购买人ID ", hidden = true)
         private Long userId;
 
+        @ApiModelProperty("是否赠送商品")
+        private Boolean giftFlag = false;
+
+
+        @ApiModelProperty("是否有畅学卡")
+        private Boolean discountFlag = false;
+
+        @ApiModelProperty("畅学卡信息")
+        private MemberPriceSettings discountInfo;
 
         @ApiModelProperty(value = "用户身份", hidden = true)
         private ClientEnum paymentClient;

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/coupon/CouponOrderWrapper.java

@@ -1,8 +1,10 @@
 package com.yonge.cooleshow.biz.dal.wrapper.coupon;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -98,6 +100,9 @@ public class CouponOrderWrapper implements Serializable {
         // 发放ID
         private Long issueId;
 
+        @ApiModelProperty("可用品类")
+        private CouponCategoryEnum category;
+
         public Double getUseLimit() {
             return Optional.ofNullable(useLimit).orElse(0D);
         }

+ 2 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/CouponInfoMapper.xml

@@ -136,9 +136,10 @@
         <result column="use_limit_" property="useLimit" />
         <result column="discount_price_" property="discountPrice" />
         <result column="issue_id" property="issueId" />
+        <result column="category_" property="category" />
     </resultMap>
     <select id="selectUserOrderCouponInfo" resultMap="UserOrderCouponInfoResultMap">
-        SELECT t1.id_, t1.name_, t1.use_limit_, t1.discount_price_, t2.id_ AS issue_id
+        SELECT t1.id_, t1.name_, t1.use_limit_, t1.discount_price_, t2.id_ AS issue_id,t1.category_
         FROM coupon_info t1 JOIN coupon_issue t2 ON t1.id_ = t2.coupon_id_
         <where>
             <if test="userId != null">