liujc 1 年之前
父節點
當前提交
271421b268
共有 29 個文件被更改,包括 1052 次插入173 次删除
  1. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/ClientEnum.java
  2. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java
  3. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ActivityPlanService.java
  4. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CacheKey.java
  5. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  6. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  7. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MemberPriceSettingsService.java
  8. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  9. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/PianoRoomBuyRecordService.java
  10. 10 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java
  11. 16 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java
  12. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantStaffService.java
  13. 17 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderService.java
  14. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VideoLessonPurchaseRecordService.java
  15. 52 18
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityPlanServiceImpl.java
  16. 51 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  17. 124 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  18. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java
  19. 96 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  20. 36 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PianoRoomBuyRecordServiceImpl.java
  21. 15 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumRefServiceImpl.java
  22. 144 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java
  23. 13 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantStaffServiceImpl.java
  24. 42 28
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  25. 168 55
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  26. 60 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonPurchaseRecordServiceImpl.java
  27. 55 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java
  28. 18 2
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java
  29. 17 54
      cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java

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

@@ -15,6 +15,7 @@ public enum ClientEnum implements BaseEnum<String, ClientEnum> {
     TENANT_STUDENT("机构-学生端"),
     SYSTEM("平台端"),
     WEBSITE("官网"),
+    TENANT("机构"),
 
     ;
     @EnumValue

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

@@ -16,6 +16,7 @@ public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
     VIDEO("视频课购买"),
     MUSIC("单曲点播"),
     ALBUM("专辑购买"),
+    TENANT_ALBUM("机构专辑"),
     PIANO_ROOM("琴房时长"),
     ACTI_REGIST("活动报名")
     ;

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

@@ -8,10 +8,12 @@ import com.yonge.cooleshow.biz.dal.dto.SaveOrUpdateRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.ActivityPlanSearch;
 import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -121,4 +123,10 @@ public interface ActivityPlanService extends IService<ActivityPlan>  {
 	 * @return
 	 */
 	YesOrNoEnum state(Long activityId);
+
+    /**
+     * 活动报名下单
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -24,7 +24,7 @@ public interface CacheKey {
     // 用户下单/付款/取消订单锁
     String PAYMENT_ORDER_LOCK = "paymentorder:{}";
     // 用户下单请求
-    String EXECUTE_ORDER_LOCK = "executeorder:{}";
+//    String EXECUTE_ORDER_LOCK = "LOCK_EXECUTE_ORDER:{}";
     // 用户支付配置
     String USER_PAYMENT_CONFIG = "paymentconfig:{}:{}";
     // 用户下单配置

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

@@ -14,6 +14,7 @@ import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.vo.res.RefundCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.base.page.PageInfo;
 import org.redisson.api.RMap;
@@ -349,5 +350,11 @@ public interface CourseGroupService extends IService<CourseGroup> {
      * @param dto
      */
     void updateLiveCourse(LiveCourseGroupDto dto);
+
+    /**
+     * 直播课购买前校验
+     *
+     */
+    void buyLiveCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }
 

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

@@ -10,8 +10,10 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
@@ -257,5 +259,11 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
     PageInfo<CourseScheduleRecordVo> selectCourseList(Map<String, Object> param);
 
     IPage<PianoClassVo> queryPianoClass(IPage<PianoClassVo> page, MyCourseSearch search);
+
+    /**
+     * 购买陪练课
+     *
+     */
+    void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }
 

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

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
 import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
@@ -14,6 +15,7 @@ import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
 import com.yonge.cooleshow.biz.dal.vo.ShareProfitVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 import java.util.List;
@@ -95,4 +97,10 @@ public interface MemberPriceSettingsService extends IService<MemberPriceSettings
      * @return
      */
     MemberPriceVo getVipShare(MemberPriceSettingsSearch query);
+
+    /**
+     * 订单创建前校验
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -16,6 +16,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetAuditSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherMusicSheetSearch;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.biz.dal.vo.HomeMusicSheetVo;
@@ -31,6 +32,7 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherMusicSheetVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherTotalVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.utils.easyexcel.ExcelDataReaderProperty;
 
@@ -362,4 +364,19 @@ public interface MusicSheetService extends IService<MusicSheet> {
      * 添加上架曲目的虚拟数
      */
     void setVirtualNumber();
+
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     * @return
+     */
+    void buyMusicSheetCheck(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
+
+    /**
+     * 购买曲目专辑
+     *
+     */
+    void orderAfterSheet(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -3,11 +3,13 @@ package com.yonge.cooleshow.biz.dal.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.vo.PianoRoomBuyRecordVo;
 import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomBuyRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.PianoRoomBuyRecord;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 /**
@@ -44,4 +46,10 @@ public interface PianoRoomBuyRecordService extends IService<PianoRoomBuyRecord>
 	 * @return
 	 */
 	void orderSuccess(UserOrderDetailVo orderDetailVo);
+
+    /**
+     * 琴房课程购买
+     *
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

+ 10 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumRefService.java

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumRefWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbumRef;
 
+import java.util.List;
+
 /**
  * 机构专辑关联表
  * 2023-07-21 17:32:49
@@ -39,5 +41,12 @@ public interface TenantAlbumRefService extends IService<TenantAlbumRef>  {
      * @return Boolean
      */
      Boolean update(TenantAlbumRefWrapper.TenantAlbumRef tenantAlbumRef);
-     
+
+    /**
+     * 根据专辑ID获取专辑关联
+     *
+     * @param tenantAlbumId 专辑ID
+     * @return
+     */
+    List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId);
 }

+ 16 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantAlbumService.java

@@ -2,8 +2,10 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 
 /**
  * 机构专辑
@@ -39,5 +41,18 @@ public interface TenantAlbumService extends IService<TenantAlbum>  {
      * @return Boolean
      */
      Boolean update(TenantAlbumWrapper.TenantAlbum tenantAlbum);
-     
+
+    /**
+     * 订单创建前检测
+     *
+     * @param orderGoodsInfo
+     */
+    void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
+
+    /**
+     * 订单完成后
+     *
+     * @param userOrderDetailVo
+     */
+    void orderSuccess(UserOrderDetailVo userOrderDetailVo);
 }

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TenantStaffService.java

@@ -40,5 +40,19 @@ public interface TenantStaffService extends IService<TenantStaff>  {
      */
      Boolean update(TenantStaffWrapper.TenantStaff tenantStaff);
 
+    /**
+     * 获取机构用户
+     *
+     * @param phone
+     * @return
+     */
     TenantStaff getByPhone(String phone);
+
+    /**
+     * 获取机构用户
+     *
+     * @param userId
+     * @return
+     */
+    TenantStaff getByUserId(Long userId);
 }

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

@@ -14,6 +14,7 @@ import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.util.Date;
@@ -121,6 +122,8 @@ public interface UserOrderService extends IService<UserOrder> {
      */
     HttpResponseResult<Boolean> orderCancel(OrderPayReq payReq);
 
+    String getGoodUrlByType(GoodTypeEnum goodTypeEnum);
+
     /***
      * 取消订单(未判断付款单状态)
      * @author liweifan
@@ -167,6 +170,13 @@ public interface UserOrderService extends IService<UserOrder> {
     Boolean setOrderStatus(UserOrder param);
 
     /**
+     * 取消订单后续处理
+     *
+     * @param userOrder
+     */
+    void payCancel(UserOrderVo userOrder);
+
+    /**
      * 订单完成
      *
      * @param detail
@@ -174,6 +184,13 @@ public interface UserOrderService extends IService<UserOrder> {
     void orderSuccess(UserOrderVo detail, PaymentCallBack data);
 
 
+    /**
+     * 支付成功后续处理
+     *
+     * @param detail
+     */
+    void paySuccess(UserOrderVo detail);
+
     Date getAccountPeriodTime(UserOrderDetailVo orderDetailVo);
 
     /**

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

@@ -1,10 +1,12 @@
 package com.yonge.cooleshow.biz.dal.service;
 
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.entity.VideoLessonPurchaseRecord;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 /**
@@ -20,4 +22,10 @@ public interface VideoLessonPurchaseRecordService extends IService<VideoLessonPu
     void buyVideoCourseSuccess(UserOrderDetailVo orderParam);
 
     void buyVideoCourseFailed(UserOrderDetailVo orderParam);
+
+    /**
+     * 购买视频课程
+     *
+     */
+    void buyVideoCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo);
 }

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

@@ -19,29 +19,13 @@ import com.yonge.cooleshow.biz.dal.dto.SaveOrUpdateRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.activity.ActivityTeacherQuery;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.ActivityPlanSearch;
-import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluation;
-import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord;
-import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
-import com.yonge.cooleshow.biz.dal.entity.ActivityPlanReward;
-import com.yonge.cooleshow.biz.dal.entity.ActivityRegistration;
-import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
-import com.yonge.cooleshow.biz.dal.entity.Student;
-import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.EQueryOp;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.activity.ActivityRankingMethodEnum;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanEvaluationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanRewardService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanStandardService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRegistrationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
-import com.yonge.cooleshow.biz.dal.service.SubjectService;
-import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.ActivityMusicVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
@@ -50,6 +34,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.activity.ActivityTeacherWrapper;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityResourceEnum;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -129,6 +114,9 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
     @Autowired
     private SubjectService subjectService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
     //保存/更新拓展字段
     private static final Map<ActivityTypeEnum, Consumer<ActivityPlanDto>> saveOrUpdateExpand = new HashMap<>();
     //开始活动(活动刚开始触发)
@@ -953,6 +941,52 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
     }
 
     /**
+     * 活动报名下单
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        log.info("活动购买 参数 --> {}", JSON.toJSONString(orderGoodsInfo));
+
+        // 检查用户
+        getSysUser(orderGoodsInfo.getUserId());
+        ActivityPlanPayDto activityPlanPayDto = JSON.parseObject(
+                JSON.toJSONString(orderGoodsInfo.getBizContent()), ActivityPlanPayDto.class);
+
+        // 检查活动购买是否已购买
+        checkActivityPay(activityPlanPayDto.getActivityId());
+
+
+        if (checkoutJoinActivity(activityPlanPayDto.getActivityId(), orderGoodsInfo.getUserId())) {
+            throw new BizException("您已经参与了活动");
+        }
+
+
+        OrderCreateRes orderCreateRes = new OrderCreateRes();
+        if (activityPlanPayDto.getActivityId() == null) {
+            throw new BizException("活动id不能为空");
+        }
+        ActivityPlan activityPlan = getById(activityPlanPayDto.getActivityId());
+
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0L);
+        userOrderDetail.setBizId(activityPlanPayDto.getActivityId());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(activityPlan.getRegistrationPrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(activityPlan.getRegistrationPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+    /**
      * 参与活动消息
      */
     private void sendMessage(String activityName, Long userId) {

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

@@ -22,6 +22,7 @@ import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -341,6 +342,56 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         coursePlanService.saveOrUpdateBatch(planList);
     }
 
+    @Override
+    public void buyLiveCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyLiveCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Map<String, Object> param = WrapperUtil.toMap(orderGoodsInfo.getBizContent());
+        Long groupId = WrapperUtil.toLong(param, "groupId", "课程组id不能为空!");
+        Long studentId = orderGoodsInfo.getUserId();
+        //校验学生信息
+        getSysUser(studentId);
+        //课程组信息
+        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("课程组课程不存在!");
+        }
+        //校验购买的课程组每节课时间是否和自己的课时冲突
+        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);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(courseGroup.getTeacherId());
+        userOrderDetail.setBizId(courseGroup.getId());
+        userOrderDetail.setBizContent(orderGoodsInfo.getBizContent());
+        userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
+        userOrderDetail.setOriginalPrice(courseGroup.getCoursePrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(courseGroup.getCoursePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyLiveCourse  return {}", userOrderDetail);
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
     /**
      * 取消课程组-下架课程组
      *

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

@@ -22,6 +22,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.enums.PostStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.payment.util.DistributedLock;
@@ -2469,4 +2470,127 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         monthToDate(search);
         return page.setRecords(baseMapper.queryPianoClass(page, search));
     }
+
+    @Override
+    public void buyPracticeCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        ObjectMapper objectMapper = new ObjectMapper();
+        PracticeScheduleDto scheduleDto = objectMapper.convertValue(orderGoodsInfo.getBizContent(), PracticeScheduleDto.class);
+
+        RLock lock = redissonClient.getLock("teacherId:" + scheduleDto.getTeacherId());
+        try {
+            if (lock.tryLock(10, 60, TimeUnit.SECONDS)) {
+                orderGoodsInfo.setUserOrderDetail( buyPracticeCourseTranV2(orderGoodsInfo));
+            }
+        } catch (InterruptedException e) {
+            throw new BizException("创建陪练课失败:{}", e.getMessage());
+        } finally {
+            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
+                lock.unlock();
+            }
+        }
+        throw  new BizException("创建陪练课失败");
+
+    }
+
+    private UserOrderDetail buyPracticeCourseTranV2(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyPracticeCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Long studentId = orderGoodsInfo.getUserId();
+
+        //校验学生信息
+        getSysUser(studentId);
+
+        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("课程数与课时数不符");
+        }
+        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());
+        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(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 = teacherFreeTimeDao.selectSubjectPrice(scheduleDto.getTeacherId(), scheduleDto.getSubjectId());
+        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.classNum(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);
+        }
+
+        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().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyPracticeCourse  return {}", userOrderDetail);
+        return userOrderDetail;
+    }
 }

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

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
@@ -22,6 +23,7 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.*;
 
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -63,6 +65,9 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     @Autowired
     private ActivityPlanService activityPlanService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
     @Override
     public MemberPriceSettingsVo detail(Long id) {
         return baseMapper.detail(id);
@@ -245,6 +250,38 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         return memberPriceVo;
     }
 
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        MemberPriceSettingsVo detail = detail(Long.parseLong(orderGoodsInfo.getBizContent()));
+        if (null == detail) {
+            throw new BizException("未找到会员卡信息");
+        }
+        BigDecimal couponAmount = BigDecimal.ZERO;
+        ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
+
+        if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
+            for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
+                if (activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
+                    couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
+                    break;
+                }
+            }
+        }
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(detail), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0l);
+        userOrderDetail.setBizId(detail.getId());
+        userOrderDetail.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(detail.getOriginalPrice());
+        userOrderDetail.setCouponAmount(couponAmount);
+        userOrderDetail.setExpectPrice(detail.getSalePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
     private void sendAddVipMessage(Long userId, ClientEnum client, Integer times, PeriodEnum type, String reason) {
         try {
             SysUser user = sysUserFeignService.queryUserById(userId);

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

@@ -57,6 +57,7 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
@@ -1553,6 +1554,101 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         this.updateBatchById(musicSheets,100);
     }
 
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     * @return
+     */
+    @Override
+    public void buyMusicSheetCheck(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+
+        // 下单前的验证
+        getSysUser(orderGoodsInfo.getUserId());
+
+        MusicSheetPayDto musicSheetPayDto = JSON.parseObject(
+                JSON.toJSONString(orderGoodsInfo.getBizContent()), MusicSheetPayDto.class);
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+
+
+        switch (orderGoodsInfo.getGoodType()) {
+            case MUSIC: // 单曲
+            {
+                MusicSheet musicSheet = this.getById(musicSheetPayDto.getMusicSheetId());
+                if (musicSheet == null) {
+                    throw new BizException("不存在曲目信息");
+                }
+
+                if (!musicSheet.getSourceType().getCode().equals(SourceTypeEnum.PLATFORM.getCode())) {
+                    userOrderDetail.setMerchId(musicSheet.getUserId());
+                }
+
+
+                userOrderDetail.setBizId(musicSheet.getId());
+                userOrderDetail.setOriginalPrice(musicSheet.getMusicPrice());
+                userOrderDetail.setExpectPrice(musicSheet.getMusicPrice());
+            }
+            break;
+            case ALBUM: // 专辑
+            {
+                MusicAlbum album = musicAlbumMapper.selectById(musicSheetPayDto.getMusicSheetId());
+
+                if (Objects.isNull(album)) {
+                    throw new BizException("无效的专辑信息");
+                }
+
+                userOrderDetail.setMerchId(0L);
+                userOrderDetail.setBizId(album.getId());
+                userOrderDetail.setOriginalPrice(BigDecimal.valueOf(album.getAlbumPrice()));
+                userOrderDetail.setExpectPrice(BigDecimal.valueOf(album.getAlbumPrice()));
+            }
+            break;
+            default:
+                break;
+        }
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        // 检查已经购买,抛出已购买异常
+        checkoutPay(orderGoodsInfo.getUserId(), musicSheetPayDto.getMusicSheetId(), musicSheetPayDto.getClientType(),
+                PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+
+    /**
+     * 购买曲目专辑
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void orderAfterSheet(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        // 保存购买记录
+        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
+                orderGoodsInfo.getUserId(),
+                orderGoodsInfo.getBizId(),
+                orderGoodsInfo.getPaymentClient(),
+                PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+        if (musicSheetPurchaseRecord == null) {
+            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
+        }
+        musicSheetPurchaseRecord.setClientType(orderGoodsInfo.getPaymentClient());
+        musicSheetPurchaseRecord.setMusicSheetId(orderGoodsInfo.getBizId());
+        musicSheetPurchaseRecord.setOrderNo(orderGoodsInfo.getOrderNo());
+        musicSheetPurchaseRecord.setTeacherId(orderGoodsInfo.getUserOrderDetail().getMerchId());
+        musicSheetPurchaseRecord.setOriginalPrice(orderGoodsInfo.getUserOrderDetail().getOriginalPrice());
+        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY);
+        musicSheetPurchaseRecord.setStudentId(orderGoodsInfo.getUserId());
+        musicSheetPurchaseRecord.setPurchaseType(PurchaseRecordTypeEnum.valueOf(orderGoodsInfo.getGoodType().getCode()));
+
+        musicSheetPurchaseRecordService.saveOrUpdate(musicSheetPurchaseRecord);
+    }
+
     @Override
     public Boolean updateMusicImg(MusicImgDto musicImgDto, Long musicSheetId) {
         MusicSheet musicSheet = new MusicSheet();

+ 36 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PianoRoomBuyRecordServiceImpl.java

@@ -1,33 +1,33 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomChangeRecord;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomTime;
-import com.yonge.cooleshow.biz.dal.entity.PlatformCashAccountRecord;
-import com.yonge.cooleshow.biz.dal.entity.UserOrder;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.PostStatusEnum;
+import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.payment.util.DistributedLock;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import com.yonge.cooleshow.biz.dal.entity.PianoRoomBuyRecord;
 import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomBuyRecordSearch;
 import com.yonge.cooleshow.biz.dal.dao.PianoRoomBuyRecordDao;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -47,6 +47,9 @@ public class PianoRoomBuyRecordServiceImpl extends ServiceImpl<PianoRoomBuyRecor
     private RedissonClient redissonClient;
 
     @Autowired
+    private UserOrderService userOrderService;
+
+    @Autowired
     private PianoRoomChangeRecordService pianoRoomChangeRecordService;
 
     @Override
@@ -119,4 +122,32 @@ public class PianoRoomBuyRecordServiceImpl extends ServiceImpl<PianoRoomBuyRecor
                         }, null, 10l);
     }
 
+    /**
+     * 琴房课程购买
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        PianoRoomSettingsVo detail = pianoRoomSettingsService.detail(Long.parseLong(orderGoodsInfo.getBizContent()));
+        if (null == detail) {
+           throw new BizException("未找到时长包");
+        }
+
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(0L);
+        userOrderDetail.setBizId(detail.getId());
+        userOrderDetail.setGoodNum(1);
+        userOrderDetail.setOriginalPrice(detail.getOriginalPrice());
+        userOrderDetail.setBizContent("琴房时长包购买-" + detail.getTimes() + "分");
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(detail.getSalePrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
 }

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

@@ -11,6 +11,8 @@ import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumRefWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.service.TenantAlbumRefService;
 
+import java.util.List;
+
 /**
  * 机构专辑关联表
  * 2023-07-21 17:32:49
@@ -63,4 +65,17 @@ public class TenantAlbumRefServiceImpl extends ServiceImpl<TenantAlbumRefMapper,
 
         return this.updateById(JSON.parseObject(tenantAlbumRef.jsonString(), TenantAlbumRef.class));       
     }
+
+    /**
+     * 根据专辑ID获取专辑关联
+     *
+     * @param tenantAlbumId 专辑ID
+     * @return
+     */
+    @Override
+    public List<TenantAlbumRef> getByAlbumId(Long tenantAlbumId) {
+        return this.lambdaQuery()
+                .eq(TenantAlbumRef::getTenantAlbumId, tenantAlbumId)
+                .list();
+    }
 }

+ 144 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantAlbumServiceImpl.java

@@ -3,13 +3,23 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.toolset.base.exception.BizException;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.BeanUtils;
 import lombok.extern.slf4j.Slf4j;
-import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
-import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.stream.Collectors;
 
 /**
  * 机构专辑
@@ -19,12 +29,27 @@ import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
 @Service
 public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, TenantAlbum> implements TenantAlbumService {
 
-	/**
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private TenantAlbumRefService tenantAlbumRefService;
+
+    @Autowired
+    private UserOrderService userOrderService;
+
+    /**
      * 查询详情
      * @param id 详情ID
      * @return TenantAlbum
      */
-	@Override
+    @Override
     public TenantAlbum detail(Long id) {
         
         return baseMapper.selectById(id);
@@ -41,15 +66,15 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
         
         return page.setRecords(baseMapper.selectPage(page, query));
     }
-	
+
     /**
      * 添加
      * @param tenantAlbum TenantAlbumWrapper.TenantAlbum
      * @return Boolean
      */
     @Override
-    public Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum) {    	
-        
+    public Boolean add(TenantAlbumWrapper.TenantAlbum tenantAlbum) {
+
         return this.save(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));
     }
 
@@ -63,4 +88,116 @@ public class TenantAlbumServiceImpl extends ServiceImpl<TenantAlbumMapper, Tenan
 
         return this.updateById(JSON.parseObject(tenantAlbum.jsonString(), TenantAlbum.class));       
     }
+
+    /**
+     * 订单创建前检测
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("订单创建前检测");
+        if (orderGoodsInfo == null) {
+            log.error("订单创建前检测,订单商品信息为空");
+            throw new BizException("订单商品信息为空");
+        }
+
+        TenantAlbumWrapper.TenantAlbumBuy tenantAlbumBuy = JSON
+                .parseObject(JSON.toJSONString(orderGoodsInfo.getBizContent()), TenantAlbumWrapper.TenantAlbumBuy.class);
+        if (tenantAlbumBuy == null) {
+            log.error("订单创建前检测,订单商品信息为空");
+            throw new BizException("订单商品信息为空");
+        }
+
+
+        // 专辑是否存在
+        TenantAlbum tenantAlbum = this.getById(orderGoodsInfo.getBizId());
+        if (tenantAlbum == null || tenantAlbum.getDelFlag() || Boolean.FALSE.equals(tenantAlbum.getStatus())) {
+            log.error("订单创建前检测,专辑不存在,bizId={}", orderGoodsInfo.getBizId());
+            throw new BizException("订单商品信息为空");
+        }
+
+        // 查询专辑所在机构
+        List<TenantAlbumRef> refList =
+                tenantAlbumRefService.getByAlbumId(tenantAlbum.getId());
+        if (CollectionUtils.isEmpty(refList)) {
+            log.error("订单创建前检测,专辑不在机构下,bizId={}", orderGoodsInfo.getBizId());
+            throw new BizException("用户不在当前机构");
+        }
+
+        // 机构ID集合
+        List<Long> tenantIdList =
+                refList.stream().map(TenantAlbumRef::getTenantId).collect(Collectors.toList());
+
+        UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
+
+        BigDecimal price = BigDecimal.ZERO;
+        // 学生购买机构专辑
+        switch (orderGoodsInfo.getPaymentClient()) {
+            case STUDENT: {
+                // 判断学生是否在当前专辑机构下
+                Student student = studentService.getById(orderGoodsInfo.getUserId());
+                if (student == null) {
+                    log.error("订单创建前检测,学生不存在,userId={}", orderGoodsInfo.getUserId());
+                    throw new BizException("用户信息未找到");
+                }
+                TenantInfo tenantInfo = tenantInfoService.detail(student.getTenantId());
+                if (tenantInfo == null || !tenantIdList.contains(tenantInfo.getId())) {
+                    log.error("订单创建前检测,学生不在当前机构下,userId={},tenantId={}", orderGoodsInfo.getUserId(), student.getTenantId());
+                    throw new BizException("用户不在当前机构");
+                }
+                price = tenantAlbum.getSalePrice();
+                userOrderDetail.setMerchId(tenantInfo.getId());
+                tenantAlbumBuy.setBuyCycle(1);
+                tenantAlbumBuy.setBuyNumber(1);
+                break;
+            }
+
+            case TENANT: {
+                // 专辑是否在机构下
+                TenantStaff tenantStaff = tenantStaffService.getByUserId(orderGoodsInfo.getUserId());
+                if (tenantStaff == null) {
+                    log.error("订单创建前检测,机构员工不存在,userId={}", orderGoodsInfo.getUserId());
+                    throw new BizException("用户信息未找到");
+                }
+                if (!tenantIdList.contains(tenantStaff.getTenantId())) {
+                    log.error("订单创建前检测,专辑不在机构下,userId={},tenantId={}", orderGoodsInfo.getUserId(), tenantStaff.getTenantId());
+                    throw new BizException("用户不在当前机构");
+                }
+                price = tenantAlbum.getOriginalPrice();
+                userOrderDetail.setMerchId(0L);
+                break;
+            }
+        }
+
+
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setBizId(tenantAlbum.getId());
+        userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
+        userOrderDetail.setOriginalPrice(price.multiply(new BigDecimal(orderGoodsInfo.getGoodNum()))
+                .multiply(new BigDecimal(tenantAlbumBuy.getBuyCycle())));
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(userOrderDetail.getOriginalPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+
+    }
+
+    /**
+     * 订单完成后
+     *
+     * @param userOrderDetailVo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void orderSuccess(UserOrderDetailVo userOrderDetailVo) {
+
+        // 学生 插入机构专辑购买数据
+
+
+        // 机构   插入机构专辑购买记录,生成机构专辑激活码
+
+    }
 }

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

@@ -69,4 +69,17 @@ public class TenantStaffServiceImpl extends ServiceImpl<TenantStaffMapper, Tenan
         return baseMapper.getByPhone(phone);
 
     }
+
+    /**
+     * 获取机构用户
+     *
+     * @param userId
+     * @return
+     */
+    @Override
+    public TenantStaff getByUserId(Long userId) {
+        return this.lambdaQuery()
+                .eq(TenantStaff::getUserId, userId)
+                .one();
+    }
 }

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

@@ -24,23 +24,7 @@ import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
 import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
 import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import com.yonge.cooleshow.biz.dal.service.ActivityRegistrationService;
-import com.yonge.cooleshow.biz.dal.service.ActivityUserRewardService;
-import com.yonge.cooleshow.biz.dal.service.CouponInfoService;
-import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
-import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
-import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
-import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
-import com.yonge.cooleshow.biz.dal.service.PianoRoomBuyRecordService;
-import com.yonge.cooleshow.biz.dal.service.PlatformCashAccountRecordService;
-import com.yonge.cooleshow.biz.dal.service.SysConfigService;
-import com.yonge.cooleshow.biz.dal.service.UserAccountService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderDetailService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderPaymentService;
-import com.yonge.cooleshow.biz.dal.service.UserOrderService;
-import com.yonge.cooleshow.biz.dal.service.VideoLessonPurchaseRecordService;
+import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
@@ -139,6 +123,9 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     @Autowired
     private CouponInfoService couponInfoService;
 
+    @Autowired
+    private TenantAlbumService tenantAlbumService;
+
     //验证订单是否可以下单,获取订单金额信息
     private static final Map<GoodTypeEnum, Function<OrderReq.OrderReqInfo, HttpResponseResult<OrderCreateRes>>> orderCreate = new HashMap<>();
     //插入订单后执行
@@ -192,6 +179,9 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         //活动报名
         orderSuccess.put(GoodTypeEnum.ACTI_REGIST, activityPlanService::orderSuccess);
 
+        //机构专辑购买
+        orderSuccess.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderSuccess);
+
         /**********订单取消后******************/
         //陪练课购买
         orderCancel.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourseFailed);
@@ -770,7 +760,8 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      * @updateTime 2022/3/31 16:49
      * @return: java.math.BigDecimal
      */
-    private String getGoodUrlByType(GoodTypeEnum goodTypeEnum) {
+    @Override
+    public String getGoodUrlByType(GoodTypeEnum goodTypeEnum) {
         String configValue = "";
         if (GoodTypeEnum.VIP.equals(goodTypeEnum)) {
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_VIP);
@@ -821,6 +812,27 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             return;
         }
 
+        payCancel(userOrder);
+        userOrder.setReason(reason);
+        userOrder.setStatus(orderStatus);
+        userOrder.setUpdateTime(new Date());
+        baseMapper.updateById(userOrder);
+
+        // 重置优惠券状态
+        couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.builder()
+                        .orderNo(userOrder.getOrderNo())
+                        .reset(true)
+                .build());
+    }
+
+    /**
+     * 取消订单后续处理
+     *
+     * @param userOrder
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void payCancel(UserOrderVo userOrder) {
         List<UserOrderDetailVo> orderDetailList = orderDetailService.getOrderDetilListByOrderNo(userOrder.getOrderNo());
         for (UserOrderDetailVo orderDetailVo : orderDetailList) {
             orderDetailVo.setUserId(userOrder.getUserId());
@@ -832,16 +844,6 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 userOrderVoConsumer.accept(orderDetailVo);
             }
         }
-        userOrder.setReason(reason);
-        userOrder.setStatus(orderStatus);
-        userOrder.setUpdateTime(new Date());
-        baseMapper.updateById(userOrder);
-
-        // 重置优惠券状态
-        couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.builder()
-                        .orderNo(userOrder.getOrderNo())
-                        .reset(true)
-                .build());
     }
 
     private void orderSuccess(UserOrderVo detail) {
@@ -896,6 +898,17 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             }
         }
 
+        paySuccess(detail);
+    }
+
+    /**
+     * 支付成功后续处理
+     *
+     * @param detail
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void paySuccess(UserOrderVo detail) {
         //调用业务
         List<UserOrderDetailVo> orderDetailList = orderDetailService.getOrderDetilListByOrderNo(detail.getOrderNo());
 
@@ -906,6 +919,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             orderDetailVo.setActivityId(detail.getActivityId());
             orderDetailVo.setRewardId(detail.getRewardId());
             orderDetailVo.setOrderType(detail.getOrderType());
+            orderDetailVo.setOrderClient(detail.getOrderClient());
 
             //记录平台收入和用户分润收入(未记录卖家收益,卖家收益业务逻辑处理)
             savePlatformAccountRecord(orderDetailVo);

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

@@ -18,15 +18,23 @@ import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentReq;
 import com.microsvc.toolkit.middleware.payment.common.api.entity.PaymentResp;
 import com.microsvc.toolkit.middleware.payment.common.api.enums.PaymentStatus;
 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.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
 import com.yonge.cooleshow.common.enums.SysUserType;
-import com.yonge.cooleshow.common.enums.payment.EGoodsType;
 import com.yonge.cooleshow.common.enums.payment.EPaymentChannel;
 import com.yonge.cooleshow.common.enums.payment.EPaymentStatus;
 import com.yonge.cooleshow.common.enums.payment.EPaymentType;
+import com.yonge.cooleshow.common.service.IdGeneratorService;
+import com.yonge.toolset.payment.core.props.PaymentProperties;
+import com.yonge.toolset.payment.core.service.PaymentClient;
 import com.yonge.toolset.payment.util.DistributedLock;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
@@ -78,32 +86,87 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
     @Autowired
     private UserOrderDetailService userOrderDetailService;
 
+    @Autowired
+    private UserOrderService userOrderService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+    @Autowired
+    private CourseGroupService courseGroupService;
+    @Autowired
+    private CourseScheduleService scheduleService;
+    @Autowired
+    private VideoLessonPurchaseRecordService recordService;
+    @Autowired
+    private MusicSheetService musicSheetService;
+    @Autowired
+    private PianoRoomBuyRecordService pianoRoomBuyRecordService;
+
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+
+    @Autowired
+    private CouponInfoService couponInfoService;
+
+    @Autowired
+    private TenantAlbumService tenantAlbumService;
+
+
 
     // 订单商品参数校验,获取订单支付金额
-    private static final Map<EGoodsType, Consumer<UserOrderDetail>> orderGoodsCreate = Maps.newHashMap();
-    // 支付订单类型参数校验
-    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderCreate = Maps.newHashMap();
+    private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderGoodsCreate = Maps.newHashMap();
+
+
     // 支付创建前,数据库存
     private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> orderSuccessBefore = Maps.newHashMap();
-    // 支付创建前,数据库存
-//    private static final Map<EPaymentType, Consumer<UserPaymentOrder>> executeSuccessBefore = Maps.newHashMap();
-    // 订单完成后执行
-    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
 
-    @PostConstruct
-    private void init() {
+    // 订单支付后
+    private static final Map<GoodTypeEnum, Consumer<UserPaymentOrderWrapper.OrderGoodsInfo>> orderSuccessAfter = Maps.newHashMap();
 
-        /*订单参数校验*/
 
-        /*支付订单类型参数校验*/
+    // 订单完成后执行
+    private static final Map<EPaymentType, Consumer<UserPaymentOrderWrapper.UserPaymentOrder>> paymentSuccess = Maps.newHashMap();
+
 
-        /*订单创建前处理流程*/
 
-        /*订单支付完成后执行*/
+    @PostConstruct
+    private void init() {
 
-        /*退款订单类型参数校验*/
+        /**********订单生成前 商品校验******************/
+        //vip开通缴费
+        orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
+        //直播课程购买
+        orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
+        //陪练课购买
+        orderGoodsCreate.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourse);
+        //视频课购买
+        orderGoodsCreate.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourse);
+        //曲目购买
+        orderGoodsCreate.put(GoodTypeEnum.MUSIC, musicSheetService::buyMusicSheetCheck);
+        // 专辑购买
+        orderGoodsCreate.put(GoodTypeEnum.ALBUM, musicSheetService::buyMusicSheetCheck);
+        //琴房时长
+        orderGoodsCreate.put(GoodTypeEnum.PIANO_ROOM, pianoRoomBuyRecordService::orderCreate);
+        //活动报名
+        orderGoodsCreate.put(GoodTypeEnum.ACTI_REGIST, activityPlanService::orderCreate);
+
+        // 机构专辑
+        orderGoodsCreate.put(GoodTypeEnum.TENANT_ALBUM, tenantAlbumService::orderCreate);
+
+        /**********订单生成后 数据处理******************/
+        //曲目购买
+        orderSuccessAfter.put(GoodTypeEnum.MUSIC, musicSheetService::orderAfterSheet);
+        // 专辑购买
+        orderSuccessAfter.put(GoodTypeEnum.ALBUM, musicSheetService::orderAfterSheet);
+
+        /**********订单完成后 数据处理******************/
+        // 沿用以前的流程
+
+        /**********订单取消后******************/
+        // 沿用以前的流程
 
-        /*退款支付完成执行*/
 
         log.info("---> orderCreate.Keys={}", orderGoodsCreate.keySet());
         log.info("---> paymentSuccess.Keys={}", paymentSuccess.keySet());
@@ -221,9 +284,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         userPaymentOrderService.updateById(order);
 
         // 不同订单类型支付成功,后续数据同步流程
-        if (paymentSuccess.containsKey(paymentOrder.getOrderType())) {
-            paymentSuccess.get(paymentOrder.getOrderType()).accept(paymentOrder);
-        }
+        userOrderService.paySuccess(userOrderService.detail(order.getId()));
 
         // 生成协议
         try {
@@ -270,46 +331,47 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                 UserPaymentOrderWrapper.UserPaymentOrder order = UserPaymentOrderWrapper.UserPaymentOrder
                     .builder()
                     .id(paymentOrder.getId())
-                    //.status(EPaymentStatus.CLOSED)
-                    //.errorMsg(errorMessage)
+                    .status(EPaymentStatus.CLOSED)
+//                    .errorMsg(errorMessage)
                     .updateTime(DateTime.now().toDate())
                     .build();
 
-                if (StringUtils.isBlank(paymentResp.getMsg())) {
 
-                    String errorMessage = null;
-                    try {
-                        // 关闭三方支付订单状态
-                        PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
-                            .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
+                String errorMessage = null;
+                try {
+                    // 关闭三方支付订单状态
+                    PaymentClose paymentClose = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVender())
+                        .close(paymentOrder.getTransNo(), "用户取消支付", paymentOrder.getOrderNo());
 
-                        if (Objects.nonNull(paymentClose)) {
-                            errorMessage = paymentClose.getMsg();
+                    if (Objects.nonNull(paymentClose)) {
+                        errorMessage = paymentClose.getMsg();
 
-                            // 订单取消,三方返回异常信息
-                            if (StringUtils.isNotEmpty(errorMessage)) {
-                                log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
-                                // 记录异常消息
-                                ThreadPool.getExecutor().submit(() -> {
-                                    order.setErrorMsg(paymentClose.getMsg());
+                        // 订单取消,三方返回异常信息
+                        if (StringUtils.isNotEmpty(errorMessage)) {
+                            log.warn("cancelPayment orderNo={}, ex={}", paymentOrder.getOrderNo(), errorMessage);
+                            // 记录异常消息
+                            ThreadPool.getExecutor().submit(() -> {
+                                order.setErrorMsg(paymentClose.getMsg());
 
-                                    // 更新订单退款异常信息
-                                    userPaymentOrderService.updateById(order);
-                                });
-                                throw new BizException("查询交易中,请耐心等待!");
-                            }
+                                // 更新订单退款异常信息
+                                userPaymentOrderService.updateById(order);
+                            });
+                            throw new BizException("查询交易中,请耐心等待!");
                         }
-                    } catch (Exception e) {
-                        log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
-                        throw new BizException("查询交易中,请耐心等待!");
                     }
-
-                    order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
+                } catch (Exception e) {
+                    log.error("cancelPayment orderNo={}", paymentOrder.getOrderNo(), e);
+                    throw new BizException("查询交易中,请耐心等待!");
                 }
 
+                order.status(EPaymentStatus.CLOSED).setErrorMsg(errorMessage);
+
                 // 更新订单关闭状态
                 userPaymentOrderService.updateById(order);
 
+                // 订单关闭后的数据处理流程
+                userOrderService.payCancel(userOrderService.detail(order.getId()));
+
             }
 
         }, 10L, TimeUnit.SECONDS);
@@ -321,17 +383,17 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
      * @param orderReq UserPaymentOrderWrapper.UserPaymentOrder
      */
     @Override
+    @Transactional
     public UserPaymentOrderWrapper.PaymentConfig executeOrderCreate(UserPaymentOrderWrapper.UserPaymentOrder orderReq) {
 
         try {
 
             // 商品校验 orderCreate
 
-
             // 用户下单请求锁
-            String lockName = redisCacheService.getExecuteOrderCacheKey(orderReq.getUserId().toString());
             // 生成用户支付订单
-            return DistributedLock.of(redissonClient).runIfLockToFunction(lockName, this::executeOrder, orderReq, 10L);
+            return DistributedLock.of(redissonClient).runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(orderReq.getUserId()),
+                    this::executeOrder, orderReq, 10L);
 
         } catch (BizException e) {
             log.error("executeOrder BizException, orderReq={}",  orderReq.jsonString(), e);
@@ -361,35 +423,74 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
             .status(EPaymentStatus.WAIT_PAY)
             .originalPrice(BigDecimal.ZERO);
 
+        List<UserOrderDetail> orderDetails = new ArrayList<>();
+        // 订单优惠券信息
+        CouponOrderWrapper couponOrderWrapper = CouponOrderWrapper.builder()
+                .discountedPrices(0D)
+                .couponInfos(Lists.newArrayList())
+                .build();
         // 购买商品信息
-        for (UserOrderDetail item : orderReq.getGoodsInfos()) {
+        for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
 
+            // 数据赋值
             item.setOrderNo(orderReq.getOrderNo());
             item.setSubOrderNo(IdWorker.getIdStr());
+            item.setActivityId(orderReq.getActivityId());
+            item.setUserId(orderReq.getUserId());
+            item.setPaymentClient(orderReq.getPaymentClient());
 
+
+            BigDecimal couponAmount = BigDecimal.ZERO;
             // 商品基本信息
             if (orderGoodsCreate.containsKey(item.getGoodType())) {
                 // 填充商品基础信息,校验参数合法以性
                 orderGoodsCreate.get(item.getGoodType()).accept(item);
+                UserOrderDetail userOrderDetail = item.getUserOrderDetail();
+                orderDetails.add(userOrderDetail);
+                // 根据优惠券计算实际优惠金额
+                // 计算优惠券金额
+                {
+                    if (StringUtils.isNotEmpty(orderReq.getCouponIds())) {
+
+                        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()));
+
+                    if (couponAmount.compareTo(userOrderDetail.getExpectPrice()) > 0) {
+                        couponAmount = userOrderDetail.getExpectPrice();
+                    }
+                    userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount).setScale(2, RoundingMode.HALF_UP));
+                    userOrderDetail.setCouponAmount(couponAmount);
+                }
             }
+
         }
 
         // 计算原始价格
-        BigDecimal originalPrice = orderReq.getGoodsInfos().stream()
+        BigDecimal originalPrice = orderDetails.stream()
             .map(UserOrderDetail::getOriginalPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
         // 支付金额
-        BigDecimal currentPrice = orderReq.getGoodsInfos().stream()
+        BigDecimal currentPrice = orderDetails.stream()
             .map(UserOrderDetail::getExpectPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
         // 实际支付金额
-        BigDecimal cashAmount = orderReq.getGoodsInfos().stream()
+        BigDecimal cashAmount = orderDetails.stream()
             .map(UserOrderDetail::getActualPrice)
             .reduce(BigDecimal.ZERO, BigDecimal::add);
 
-        // 根据优惠券计算实际优惠金额
 
         orderReq.originalPrice(originalPrice.setScale(2, RoundingMode.HALF_UP))
             .currentPrice(currentPrice.setScale(2, RoundingMode.HALF_UP))
@@ -418,11 +519,23 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         }
         userPaymentOrderService.save(orderReq);
 
-        userOrderDetailService.saveBatch(orderReq.getGoodsInfos());
+        userOrderDetailService.saveBatch(orderDetails);
+
+        // 入库后处理流程
+        for (UserPaymentOrderWrapper.OrderGoodsInfo item : orderReq.getGoodsInfos()) {
+            if (orderSuccessAfter.containsKey(item.getGoodType())) {
+                orderSuccessAfter.get(item.getGoodType()).accept(item);
+            }
+        }
 
         // 更新用户订单优惠券使用状态
+        if (CollectionUtils.isNotEmpty(couponOrderWrapper.getCouponInfos())) {
+
+            couponOrderWrapper.useType(CouponCategoryEnum.goodTypeTo(orderReq.getOrderType().getCode()));
+            couponInfoService.updateUserOrderCouponInfo(couponOrderWrapper.orderNo(orderReq.getOrderNo()));
+        }
 
-        String subject = orderReq.getGoodsInfos().stream()
+        String subject = orderDetails.stream()
             .map(UserOrderDetail::getGoodName).collect(Collectors.joining(","));
         // 返回订单支付配置参数
         UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig

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

@@ -19,6 +19,7 @@ import com.yonge.cooleshow.biz.dal.enums.course.CourseRelationTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseRelationWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -272,6 +273,65 @@ public class VideoLessonPurchaseRecordServiceImpl extends ServiceImpl<VideoLesso
     }
 
     /**
+     * 购买视频课程
+     *
+     * @param orderGoodsInfo
+     */
+    @Override
+    public void buyVideoCourse(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
+        log.info("buyVideoCourse  param:{}", JSON.toJSONString(orderGoodsInfo));
+        Long studentId = orderGoodsInfo.getUserId();
+        String orderNo = orderGoodsInfo.getOrderNo();
+
+        //校验学生信息
+        getSysUser(studentId);
+
+        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("课程组不存在!");
+        }
+
+        //校验课程是否购买
+        VideoLessonPurchaseRecord isAlreadyBuy = videoLessonPurchaseRecordDao.selectOne(Wrappers.<VideoLessonPurchaseRecord>lambdaQuery()
+                .eq(VideoLessonPurchaseRecord::getStudentId, studentId)
+                .eq(VideoLessonPurchaseRecord::getVideoLessonGroupId, groupId));
+        if (!ObjectUtil.isEmpty(isAlreadyBuy)) {
+            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);
+
+        userOrderDetail.setGoodUrl(userOrderService.getGoodUrlByType(orderGoodsInfo.getGoodType()));
+        userOrderDetail.setMerchId(lessonGroup.getTeacherId());
+        userOrderDetail.setBizId(lessonGroup.getId());
+        userOrderDetail.setGoodNum(lessonGroup.getLessonCount());
+        userOrderDetail.setOriginalPrice(lessonGroup.getLessonPrice());
+        userOrderDetail.setCouponAmount(BigDecimal.ZERO);
+        userOrderDetail.setExpectPrice(lessonGroup.getLessonPrice());
+        userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(userOrderDetail.getCouponAmount()));
+
+        log.info("buyVideoCourse  return {}", userOrderDetail);
+
+        orderGoodsInfo.setUserOrderDetail(userOrderDetail);
+    }
+
+    /**
      * 获取用户信息
      */
     private SysUser getSysUser(Long userId) {

+ 55 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserPaymentOrderWrapper.java

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderPayment;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.common.enums.payment.EGoodsType;
@@ -164,6 +165,8 @@ public class UserPaymentOrderWrapper {
         @ApiModelProperty("支付厂商名")
         private String paymentVenderName;
 
+        @ApiModelProperty("优惠券Id;多个使用,隔开")
+        private String couponIds;
 
         @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
         private Long recomUserId;
@@ -250,7 +253,7 @@ public class UserPaymentOrderWrapper {
 
 
         @ApiModelProperty("商品信息")
-        private List<UserOrderDetail> goodsInfos;
+        private List<OrderGoodsInfo> goodsInfos;
 
 
         @ApiModelProperty("支付配置参数")
@@ -793,4 +796,55 @@ public class UserPaymentOrderWrapper {
         }
     }
 
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("订单商品信息")
+    public static class OrderGoodsInfo implements Serializable {
+
+
+        @ApiModelProperty("优惠券Id")
+        private Long couponId;
+
+        @ApiModelProperty(value = "活动id",hidden = true)
+        private Long activityId;
+
+        @ApiModelProperty(value = "订单号 ",hidden = true)
+        private String orderNo;
+
+        @ApiModelProperty(value = "订单详情号 ",hidden = true)
+        private String subOrderNo;
+
+        @ApiModelProperty("订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长)")
+        private GoodTypeEnum goodType;
+
+        @ApiModelProperty("业务id ")
+        private Long bizId;
+        @ApiModelProperty("业务内容 ")
+        private String bizContent;
+
+
+        @ApiModelProperty("商品数量 ")
+        private Integer goodNum;
+
+        @ApiModelProperty("商品名称 ")
+        private String goodName;
+
+        @ApiModelProperty(value = "购买人ID ",hidden = true)
+        private Long userId;
+
+
+        @ApiModelProperty("用户身份")
+        private ClientEnum paymentClient;
+
+        @ApiModelProperty(value = "生成的订单详情信息",hidden = true)
+        private UserOrderDetail userOrderDetail;
+
+        public Integer getGoodNum() {
+            return Optional.ofNullable(goodNum).orElse(1);
+        }
+    }
+
 }

+ 18 - 2
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java

@@ -5,6 +5,9 @@ import com.alibaba.fastjson.JSONObject;
 import com.microsvc.toolkit.common.response.template.R;
 import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.tenant.vo.UserPaymentOrderVo;
@@ -26,6 +29,8 @@ import java.util.Objects;
 public class UserOrderController {
 
 
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
 
     @Autowired
     private UserPaymentCoreService userPaymentCoreService;
@@ -35,6 +40,12 @@ public class UserOrderController {
     public R<UserPaymentOrderWrapper.PaymentConfig> executeOrder(@Validated @RequestBody UserPaymentOrderVo.OrderReq orderReq) {
 
         // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
+        orderReq.setUserId(sysUser.getId());
+        orderReq.setPaymentClient(ClientEnum.TENANT.name());
 
 
         // 用户下单请求
@@ -51,14 +62,19 @@ public class UserOrderController {
     @ApiOperation(value = "用户付款", notes = "用户付款")
     @PostMapping("/executePayment")
     public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config) {
-
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
 
 
         // 用户下单请求
         UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
 
         // 创建用户支付数据
-        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(new JwtUserInfo<>(), reqConfig);
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(sysUser.getId().toString()).clientType(ClientEnum.TEACHER.getCode()).build(), reqConfig);
         if (Objects.isNull(paymentConfig)) {
             throw BizException.from("付款失败");
         }

+ 17 - 54
cooleshow-user/user-tenant/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java

@@ -1,13 +1,20 @@
 package com.yonge.cooleshow.tenant.vo;
 
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import org.springframework.format.annotation.DateTimeFormat;
 
+import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
@@ -128,8 +135,9 @@ public class UserPaymentOrderVo {
         @ApiModelProperty("业务类型Id")
         private String bizId;
 
-        @ApiModelProperty("订单类型:  VIP(开通会员), ORCHESTRA(乐团报名)")
-        private String orderType;
+        @NotNull(message = "订单类型不能为空")
+        @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
+        private OrderTypeEnum orderType;
 
         @ApiModelProperty("现价")
         private BigDecimal currentPrice;
@@ -153,7 +161,7 @@ public class UserPaymentOrderVo {
         private String couponIds;
 
         @ApiModelProperty("订单商品信息")
-        private List<OrderGoodsInfo> goodsInfos;
+        private List<UserPaymentOrderWrapper.OrderGoodsInfo> goodsInfos;
 
         @ApiModelProperty(value = "用户身份", hidden = true)
         private String paymentClient;
@@ -161,6 +169,12 @@ public class UserPaymentOrderVo {
         @ApiModelProperty(value = "用户编号", hidden = true)
         private Long userId;
 
+        @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
+        private Long recomUserId;
+
+        @ApiModelProperty(value = "活动id")
+        private Long activityId;
+
         public String jsonString() {
             return JSON.toJSONString(this);
         }
@@ -180,57 +194,6 @@ public class UserPaymentOrderVo {
     @Builder
     @NoArgsConstructor
     @AllArgsConstructor
-    @ApiModel("订单商品信息")
-    public static class OrderGoodsInfo implements Serializable {
-
-        @ApiModelProperty("商品类型 ")
-        private String goodsType;
-
-        @ApiModelProperty("商品名称")
-        private String goodsName;
-
-        @ApiModelProperty("商品图片")
-        private String goodsUrl;
-
-        @ApiModelProperty("商品Id")
-        private String goodsId;
-
-        @ApiModelProperty("商品库存Id")
-        private Long goodsSkuId;
-
-        @ApiModelProperty("商品来源")
-        private String goodsSource;
-
-        @ApiModelProperty("商品描述")
-        private String description;
-
-        @ApiModelProperty("原价")
-        private BigDecimal originalPrice;
-
-        @ApiModelProperty("现价")
-        private BigDecimal currentPrice;
-
-        @ApiModelProperty("实付现金")
-        private BigDecimal paymentCashAmount;
-
-        @ApiModelProperty("优惠金额")
-        private BigDecimal paymentCouponAmount;
-
-        @ApiModelProperty("商品数量")
-        private Integer goodsNum;
-
-        @ApiModelProperty("优惠券Id")
-        private Long couponId;
-
-        public Integer getGoodsNum() {
-            return Optional.ofNullable(goodsNum).orElse(1);
-        }
-    }
-
-    @Data
-    @Builder
-    @NoArgsConstructor
-    @AllArgsConstructor
     @ApiModel("订单支付参数配置")
     public static class PaymentReqConfig implements Serializable {