Browse Source

Merge branch 'zx_online_update_1218' of http://git.dayaedu.com/yonge/cooleshow into feature/1219_opt

zouxuan 1 day ago
parent
commit
c908baa272
72 changed files with 820 additions and 617 deletions
  1. 7 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AdminCourseGroupController.java
  2. 7 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java
  3. 1 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java
  4. 1 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/CourseHomeworkController.java
  5. 8 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseGroupController.java
  6. 3 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseScheduleController.java
  7. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java
  8. 2 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseHomeworkController.java
  9. 13 7
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseGroupController.java
  10. 7 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java
  11. 15 18
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java
  12. 2 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/WebCourseScheduleController.java
  13. 19 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  14. 1 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentType.java
  15. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseGroupDao.java
  16. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderRefundBillDao.java
  17. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderRefundDao.java
  18. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/CheckCourseTimeDto.java
  19. 22 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/LiveCourseGroupDto.java
  20. 2 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupSearch.java
  21. 4 95
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/HomeworkSearch.java
  22. 7 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/OrderSearch.java
  23. 10 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseGroup.java
  24. 7 97
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentTime.java
  25. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/AccountBizTypeEnum.java
  26. 3 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/CourseScheduleEnum.java
  27. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java
  28. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java
  29. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/OrderTypeEnum.java
  30. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponCategoryEnum.java
  31. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/course/CourseTypeEnum.java
  32. 9 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  33. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderRefundBillService.java
  34. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderRefundService.java
  35. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentCoreService.java
  36. 192 23
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  37. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseHomeworkServiceImpl.java
  38. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseRepliedServiceImpl.java
  39. 55 32
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  40. 0 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleStudentPaymentServiceImpl.java
  41. 6 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  42. 13 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  43. 14 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentTimeServiceImpl.java
  44. 34 63
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysUserServiceImpl.java
  45. 12 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserAccountServiceImpl.java
  46. 9 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderRefundBillServiceImpl.java
  47. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderRefundServiceImpl.java
  48. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  49. 67 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  50. 12 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupVo.java
  51. 25 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseInfoVo.java
  52. 5 71
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseRepliedVo.java
  53. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseStudent.java
  54. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseGroupVo.java
  55. 0 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseInfoVo.java
  56. 4 119
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MyRepliedVo.java
  57. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherLiveCourseInfoVo.java
  58. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/res/AccountTotal.java
  59. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/course/CourseScheduleWrapper.java
  60. 56 34
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml
  61. 11 3
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseHomeworkMapper.xml
  62. 21 14
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml
  63. 2 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleRepliedMapper.xml
  64. 11 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml
  65. 6 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentTimeMapper.xml
  66. 5 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml
  67. 3 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserAccountMapper.xml
  68. 3 3
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserAccountRecordMapper.xml
  69. 10 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderMapper.xml
  70. 6 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderRefundBillMapper.xml
  71. 8 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderRefundMapper.xml
  72. 1 1
      pom.xml

+ 7 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/AdminCourseGroupController.java

@@ -18,6 +18,7 @@ import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -43,7 +44,9 @@ public class AdminCourseGroupController extends BaseController {
     @PostMapping(value="/live/list", consumes="application/json", produces="application/json")
     public HttpResponseResult<PageInfo<LiveCourseGroupVo>> teacherList(@Validated(value = LiveCourseGroupSearch.TeacherGroup.class)
                                                                            @RequestBody LiveCourseGroupSearch query) {
-        query.setCourseType(CourseScheduleEnum.LIVE);
+        if(query.getCourseType() == null){
+            query.setCourseType(CourseScheduleEnum.LIVE);
+        }
 
         IPage<LiveCourseGroupVo> liveCourseGroupVoIPage = courseGroupService
                 .selectAdminLivePage(PageUtil.getPage(query), query);
@@ -55,7 +58,9 @@ public class AdminCourseGroupController extends BaseController {
     @PostMapping(value="/live/list/student", consumes="application/json", produces="application/json")
     public HttpResponseResult<PageInfo<LiveCourseGroupVo>> studentList(@Validated(value = LiveCourseGroupSearch.StudentGroup.class)
                                                                            @RequestBody LiveCourseGroupSearch query) {
-        query.setCourseType(CourseScheduleEnum.LIVE);
+        if(query.getCourseType() == null){
+            query.setCourseType(CourseScheduleEnum.LIVE);
+        }
 
         IPage<LiveCourseGroupVo> liveCourseGroupVoIPage = courseGroupService
                 .selectAdminLivePage(PageUtil.getPage(query), query);

+ 7 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java

@@ -12,10 +12,12 @@ import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import javax.validation.constraints.NotNull;
 import java.util.List;
 
@@ -28,9 +30,9 @@ import java.util.List;
 @Api(tags = "课程组")
 @Validated
 public class CourseGroupController extends BaseController {
-    @Autowired
+    @Resource
     private CourseGroupService courseGroupService;
-    @Autowired
+    @Resource
     private CourseScheduleService courseScheduleService;
 
     @ApiOperation(value = "课程组管理-趣纠课", notes = "{\n" +
@@ -65,6 +67,9 @@ public class CourseGroupController extends BaseController {
             "}")
     @PostMapping(value = "/live")
     public HttpResponseResult<PageInfo<CourseGroupLiveVo>> selectLiveGroup(@RequestBody CourseGroupSearch search) {
+        if(StringUtils.isEmpty(search.getGroupType())){
+            search.setGroupType("LIVE");
+        }
         return succeed(PageUtil.pageInfo(courseGroupService.selectLiveGroup(PageUtil.getPage(search), search)));
     }
 

+ 1 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/task/TaskController.java

@@ -92,6 +92,7 @@ public class TaskController extends BaseController {
     public HttpResponseResult pollingOrder() {
         userOrderService.pollingOrder();
         userPaymentCoreService.scanPaymentTimeoutOrderRecord();
+        userPaymentCoreService.scanRefundOrderRecord();
         return succeed();
     }
 

+ 1 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/CourseHomeworkController.java

@@ -100,6 +100,7 @@ public class CourseHomeworkController extends BaseController {
         list.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
         list.add(CourseScheduleEnum.PRACTICE);
         list.add(CourseScheduleEnum.VIP);
+        list.add(CourseScheduleEnum.GROUP);
         query.setCourseType(list);
 
         IPage<CourseHomeworkVo> page = courseHomeworkService.selectPage(PageUtil.getPage(query), query);

+ 8 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseGroupController.java

@@ -8,6 +8,7 @@ import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
 import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseInfoVo;
 import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseGroupWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -46,12 +47,19 @@ public class StudentCourseGroupController extends BaseController {
         return succeed(courseGroupService.queryLiveCourseInfo(groupId));
     }
 
+    @ApiOperation("课程组详情")
+    @GetMapping("/queryCourseInfo")
+    public HttpResponseResult<CourseInfoVo> queryCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryCourseInfo(groupId));
+    }
+
     @ApiImplicitParams({
             @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
             @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
             @ApiImplicitParam(name = "groupStatus", dataType = "String", value = "课程组状态  ING(进行中)  NOT_SALE(未开售,未上架) APPLY(报名中,销售中) COMPLETE(已完成)"),
             @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
             @ApiImplicitParam(name = "subjectId", dataType = "Integer", value = "声部id"),
+            @ApiImplicitParam(name = "courseType", dataType = "String", value = "课程类型"),
             @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
             @ApiImplicitParam(name = "version", dataType = "String", value = "版本"),
             @ApiImplicitParam(name = "platform", dataType = "Integer", value = "平台"),

+ 3 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseScheduleController.java

@@ -8,6 +8,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.wrapper.TeacherFreeTimeWrapper;
@@ -105,12 +106,14 @@ public class StudentCourseScheduleController extends BaseController {
             @ApiImplicitParam(name = "classDate", dataType = "String", required = true, value = "年月"),
             @ApiImplicitParam(name = "courseState", dataType = "String", value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成 CANCEL已取消"),
             @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "courseType", dataType = "String", value = "课程类型"),
             @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
             @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
     })
     @ApiOperation("学生-查询直播课")
     @PostMapping("/queryStudentLiveCourse")
     public HttpResponseResult<PageInfo<CourseStudent>> queryStudentLiveCourse(@RequestBody Map<String, Object> param) {
+        param.put("type", param.get("courseType") == null ? CourseScheduleEnum.LIVE.getCode() : param.get("courseType"));
         return succeed(courseScheduleService.queryStudentLiveCourse(param));
     }
 

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java

@@ -318,7 +318,7 @@ public class UserOrderController extends BaseController {
         // 新增数据
         UserPaymentOrderWrapper.PaymentConfig paymentConfig = userPaymentCoreService.executeOrderCreate(order);
         if (Objects.isNull(paymentConfig)) {
-            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("下单失败");
+            throw new BizException("下单失败");
         }
 
         return R.from(paymentConfig);

+ 2 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseHomeworkController.java

@@ -143,7 +143,9 @@ public class CourseHomeworkController extends BaseController {
         list.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
         list.add(CourseScheduleEnum.PRACTICE);
         list.add(CourseScheduleEnum.VIP);
+        list.add(CourseScheduleEnum.GROUP);
         query.setCourseType(list);
+        query.setClientType("TEACHER");
 
         IPage<CourseHomeworkVo> page = courseHomeworkService.selectPage(PageUtil.getPage(query), query);
         if (CollectionUtils.isNotEmpty(page.getRecords())) {

+ 13 - 7
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseGroupController.java

@@ -2,28 +2,24 @@ package com.yonge.cooleshow.teacher.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
-import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
 import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
 import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
 import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
 import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
-import com.yonge.cooleshow.biz.dal.service.SysMessageService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
 import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseInfoVo;
 import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
-import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseGroupWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
-import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import io.swagger.annotations.*;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -59,17 +55,24 @@ public class TeacherCourseGroupController extends BaseController {
         return succeed(courseGroupService.queryLiveCourseInfo(groupId));
     }
 
+    @ApiOperation("课程组详情")
+    @GetMapping("/queryCourseInfo")
+    public HttpResponseResult<CourseInfoVo> queryCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryCourseInfo(groupId));
+    }
+
     @ApiImplicitParams({
             @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
             @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
             @ApiImplicitParam(name = "groupStatus", dataType = "String", value = "课程组状态  ING(进行中)  NOT_SALE(未开售,未上架) APPLY(报名中,销售中) COMPLETE(已完成) OUT_SALE(已下架)"),
             @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
             @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+            @ApiImplicitParam(name = "courseType", dataType = "String", value = "课程类型"),
             @ApiImplicitParam(name = "myself", dataType = "Boolean", value = "查看我自己的直播课"),
             @ApiImplicitParam(name = "version", dataType = "String", value = "版本"),
             @ApiImplicitParam(name = "platform", dataType = "Integer", value = "平台"),
     })
-    @ApiOperation("分页查询直播课课程组列表")
+    @ApiOperation("分页查询直播课、小组课 课程组列表")
     @PostMapping("/queryPageCourseGroup")
     public HttpResponseResult<PageInfo<CourseGroupVo>> queryPageLiveCourseGroup(@RequestBody Map<String, Object> param) {
 
@@ -103,6 +106,9 @@ public class TeacherCourseGroupController extends BaseController {
         if (appAuditVersion == YesOrNoEnum.NO && dto.getCoursePrice().compareTo(BigDecimal.ZERO) <= 0) {
             return failed("课程价格不能为0元");
         }
+        if(StringUtils.isEmpty(dto.getCourseType())){
+            dto.setCourseType(CourseScheduleEnum.LIVE.getCode());
+        }
         courseGroupService.addLiveCourse(dto);
         return succeed();
     }

+ 7 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.teacher.controller;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
 import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
@@ -17,6 +18,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -50,12 +52,14 @@ public class TeacherCourseScheduleController extends BaseController {
             @ApiImplicitParam(name = "classDate", dataType = "Integer", value = "年月"),
             @ApiImplicitParam(name = "status", dataType = "String", value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成"),
             @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "courseType", dataType = "String", value = "课程类型"),
             @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
             @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
     })
     @ApiOperation("老师端-首页-我的课程-直播课")
     @PostMapping("/queryTeacherLiveCourse")
     public HttpResponseResult<PageInfo<TeacherLiveCourseInfoVo>> queryTeacherLiveCourse(@RequestBody Map<String, Object> param) {
+        param.put("type",param.get("courseType") == null? CourseScheduleEnum.LIVE.getCode():param.get("courseType").toString());
         return succeed(courseScheduleService.queryTeacherLiveCourse(param));
     }
 
@@ -100,7 +104,9 @@ public class TeacherCourseScheduleController extends BaseController {
     @PostMapping("/queryTeacherPracticeCourse")
     public HttpResponseResult<PageInfo<MyCourseVo>> queryTeacherPracticeCourse(@RequestBody MyCourseSearch search) {
         search.setTeacherId(sysUserService.getUserId());
-        search.setCourseType("VIP,PRACTICE");
+        if(StringUtils.isEmpty(search.getCourseType())){
+            search.setCourseType("VIP,PRACTICE,GROUP");
+        }
         IPage<MyCourseVo> pages = courseScheduleService.queryTeacherPracticeCourse(PageUtil.getPage(search), search);
         return succeed(PageUtil.pageInfo(pages));
     }

+ 15 - 18
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java

@@ -4,26 +4,17 @@ package com.yonge.cooleshow.website.controller;
 import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
 import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
 import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
-import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
 import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseInfoVo;
 import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
-import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiImplicitParam;
-import io.swagger.annotations.ApiImplicitParams;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.*;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
@@ -43,17 +34,21 @@ public class CourseGroupController extends BaseController {
     /**
      * 服务对象
      */
-    @Autowired
+    @Resource
     private CourseGroupService courseGroupService;
 
-    @Resource
-    private AppVersionInfoService appVersionInfoService;
     @ApiOperation("直播课详情")
     @GetMapping("/queryLiveCourseInfo")
     public HttpResponseResult<LiveCourseInfoVo> queryLiveCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
         return succeed(courseGroupService.queryLiveCourseInfo(groupId));
     }
 
+    @ApiOperation("课程组详情")
+    @GetMapping("/queryCourseInfo")
+    public HttpResponseResult<CourseInfoVo> queryCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryCourseInfo(groupId));
+    }
+
     @ApiImplicitParams({
             @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
             @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
@@ -70,10 +65,12 @@ public class CourseGroupController extends BaseController {
     @ApiOperation("创建直播课程组-新增课程组")
     @PostMapping("/addLiveCourse")
     public HttpResponseResult<Object> addLiveCourse(@RequestBody LiveCourseGroupDto dto) {
-
         if (dto.getCoursePrice().compareTo(BigDecimal.ZERO) <= 0) {
             return failed("课程价格不能为0元");
         }
+        if(StringUtils.isEmpty(dto.getCourseType())){
+            dto.setCourseType(CourseScheduleEnum.LIVE.getCode());
+        }
         courseGroupService.addLiveCourse(dto);
         return succeed();
     }

+ 2 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/WebCourseScheduleController.java

@@ -5,6 +5,7 @@ import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
 import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
 import com.yonge.cooleshow.biz.dal.vo.ArrangeCourseVo;
@@ -67,6 +68,7 @@ public class WebCourseScheduleController extends BaseController {
     @ApiOperation("老师端-首页-我的课程-直播课")
     @PostMapping("/queryTeacherLiveCourse")
     public HttpResponseResult<PageInfo<TeacherLiveCourseInfoVo>> queryTeacherLiveCourse(@RequestBody Map<String, Object> param) {
+        param.put("type",param.get("courseType") == null? CourseScheduleEnum.LIVE.getCode():param.get("courseType").toString());
         return succeed(courseScheduleService.queryTeacherLiveCourse(param));
     }
 

+ 19 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java

@@ -37,6 +37,10 @@ public interface SysConfigConstant {
      */
     String LIVE_SERVICE_RATE = "live_service_rate";
     /**
+     * 小组课服务费
+     */
+    String GROUP_SERVICE_RATE = "group_service_rate";
+    /**
      * 视频课服务费
      */
     String VIDEO_LESSON_SERVICE_FEE = "video_lesson_service_fee";
@@ -57,6 +61,10 @@ public interface SysConfigConstant {
      */
     String PRE_CREATE_VIP_ROOM_MINUTE = "pre_create_vip_course_room_minute";
     /**
+     * 提前XX分钟创建/进入小组课房间时间
+     */
+    String PRE_CREATE_GROUP_ROOM_MINUTE = "pre_create_group_course_room_minute";
+    /**
      * 直播结束后,XX分钟关闭房间
      */
     String DESTROY_EXPIRED_LIVE_ROOM_MINUTE = "destroy_expired_live_room_minute";
@@ -69,6 +77,10 @@ public interface SysConfigConstant {
      */
     String DESTROY_EXPIRED_VIP_ROOM_MINUTE = "destroy_expired_vip_course_room_minute";
     /**
+     * 小组课结束后,XX分钟关闭房间
+     */
+    String DESTROY_EXPIRED_GROUP_ROOM_MINUTE = "destroy_expired_group_course_room_minute";
+    /**
      * 课程结束后,XX天后结算课酬
      */
     String COURSE_SETTLEMENT_TIME_DAY = "course_settlement_time_day";
@@ -137,6 +149,7 @@ public interface SysConfigConstant {
      */
     String GOOD_LOGO_PRACTICE = "good_logo_practice";
     String GOOD_LOGO_VIP_COURSE = "good_logo_vip_course";
+    String GOOD_LOGO_GROUP = "good_logo_group";
     /***
      * 商品直播课图片
      * @author liweifan
@@ -320,6 +333,7 @@ public interface SysConfigConstant {
      * vip课帐期
      */
     String VIP_COURSE_ACCOUNT_PERIOD = "vip_course_account_period";
+    String GROUP_COURSE_ACCOUNT_PERIOD = "group_course_account_period";
 
     /**
      * 直播课账期
@@ -500,4 +514,9 @@ public interface SysConfigConstant {
     String COURSE_SUBJECT_MAP = "course_subject_map";
     String ADAPAY_CLOSE_ORDER_NOTIFY = "adapay_close_order_notify";
     String LOGOFF_IMG = "logoff_img";
+
+    /**
+     *小组课最大成课人数
+     */
+    String GROUP_MAX_STUDENT_NUM = "group_max_student_num";
 }

+ 1 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentType.java

@@ -13,6 +13,7 @@ public enum EPaymentType {
     SVIP("开通会员 SVIP"),
     PRACTICE("趣纠课购买"),
     LIVE("直播课购买"),
+    GROUP("小组课购买"),
     VIDEO("视频课购买"),
     MUSIC("单曲点播"),
     PIANO_ROOM("琴房时长"),

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseGroupDao.java

@@ -274,5 +274,7 @@ public interface CourseGroupDao extends BaseMapper<CourseGroup> {
     void updateCompleteCourseNum(@Param("groupIds") List<Long> groupIds);
 
     void updateExposureNum(@Param("groupId") Long groupId, @Param("exposureNum") Integer exposureNum);
+
+    int updateLockNum(@Param("groupId") Long groupId, @Param("num") int num);
 }
 

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderRefundBillDao.java

@@ -28,4 +28,6 @@ public interface UserOrderRefundBillDao extends BaseMapper<UserOrderRefundBill>{
 	List<UserOrderRefundBillVo> selectPage(@Param("page") IPage page, @Param("param") UserOrderRefundPaymentSearch userOrderRefundPayment);
 
     UserOrderRefundBill getByTransNoOrOrderNo(@Param("transNo") String transNo, @Param("refundOrderNo") String refundOrderNo);
+
+    List<UserOrderRefundBill> getPendingList();
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserOrderRefundDao.java

@@ -38,4 +38,6 @@ public interface UserOrderRefundDao extends BaseMapper<UserOrderRefund> {
      * @return: java.util.List<com.yonge.cooleshow.biz.dal.entity.UserOrderDetail>
      */
     List<UserOrderDetail> selectOrderRefundDetils(@Param("orderId") Long orderId);
+
+    List<UserOrderRefund> getByOrderNo(@Param("orderNo") String orderNo, @Param("orderDetailIds") List<Long> orderDetailIds);
 }

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/CheckCourseTimeDto.java

@@ -25,7 +25,7 @@ public class CheckCourseTimeDto implements Serializable {
     private Integer loop;
 
     @NotBlank(message = "课程类型不能为空")
-    @ApiModelProperty(value = "PRACTICE:趣纠课,LIVE:直播课")
+    @ApiModelProperty(value = "PRACTICE:趣纠课,LIVE:直播课 GROUP 小组课")
     private String  courseType;
 
     @NotNull(message = "课程数不能为空")

+ 22 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/LiveCourseGroupDto.java

@@ -76,7 +76,13 @@ public class LiveCourseGroupDto implements Serializable {
     @ApiModelProperty(value = "最少成课人数")
     private Integer mixStudentNum;
 
+    @NotNull(message = "最少成课人数不能为空")
+    @Positive(message = "最少成课人数必须大于0")
+    @ApiModelProperty(value = "最少成课人数")
+    private Integer maxStudentNum;
 
+    @ApiModelProperty(value = "课程类型")
+    private String courseType;
 
     @NotNull(message = "课程休息时长不能为空")
     @ApiModelProperty(value = "课程休息时长")
@@ -143,6 +149,22 @@ public class LiveCourseGroupDto implements Serializable {
         }
     }
 
+    public Integer getMaxStudentNum() {
+        return maxStudentNum;
+    }
+
+    public void setMaxStudentNum(Integer maxStudentNum) {
+        this.maxStudentNum = maxStudentNum;
+    }
+
+    public String getCourseType() {
+        return courseType;
+    }
+
+    public void setCourseType(String courseType) {
+        this.courseType = courseType;
+    }
+
     public Integer getCourseFreeMinutes() {
         return courseFreeMinutes;
     }

+ 2 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupSearch.java

@@ -70,6 +70,6 @@ public class CourseGroupSearch extends QueryInfo {
     @ApiModelProperty(value = "是否草稿 (0:否  1:是)",hidden = true)
     private Integer draftFlag;
 
-    @ApiModelProperty(value = "课程组类型 VIP 、PRACTICE")
-    private String groupType = "PRACTICE";
+    @ApiModelProperty(value = "课程组类型 VIP 、PRACTICE、GROUP")
+    private String groupType;
 }

+ 4 - 95
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/HomeworkSearch.java

@@ -7,6 +7,7 @@ import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
 import java.util.Date;
@@ -18,6 +19,7 @@ import java.util.List;
  * @author liujunchi
  * @date 2022-04-13
  */
+@Data
 @ApiModel("课后作业查询条件")
 public class HomeworkSearch extends QueryInfo {
 
@@ -61,99 +63,6 @@ public class HomeworkSearch extends QueryInfo {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
     private Date endTime;
 
-    public HomeworkStatusEnum getHomeworkStatus() {
-        return homeworkStatus;
-    }
-
-    public void setHomeworkStatus(HomeworkStatusEnum homeworkStatus) {
-        this.homeworkStatus = homeworkStatus;
-    }
-
-    public Long getCourseScheduleId() {
-        return courseScheduleId;
-    }
-
-    public void setCourseScheduleId(Long courseScheduleId) {
-        this.courseScheduleId = courseScheduleId;
-    }
-
-    public Long getTeacherId() {
-        return teacherId;
-    }
-
-    public void setTeacherId(Long teacherId) {
-        this.teacherId = teacherId;
-    }
-
-    public List<CourseScheduleEnum> getCourseType() {
-        return courseType;
-    }
-
-    public void setCourseType(List<CourseScheduleEnum> courseType) {
-        this.courseType = courseType;
-    }
-
-    public CourseScheduleEnum getCourseStatus() {
-        return courseStatus;
-    }
-
-    public void setCourseStatus(CourseScheduleEnum courseStatus) {
-        this.courseStatus = courseStatus;
-    }
-
-    public YesOrNoEnum getDecorate() {
-        return decorate;
-    }
-
-    public void setDecorate(YesOrNoEnum decorate) {
-        this.decorate = decorate;
-    }
-
-    public String getDate() {
-        return date;
-    }
-
-    public void setDate(String date) {
-        this.date = date;
-    }
-
-    public YesOrNoEnum getSubmit() {
-        return submit;
-    }
-
-    public void setSubmit(YesOrNoEnum submit) {
-        this.submit = submit;
-    }
-
-    public Long getStudentId() {
-        return studentId;
-    }
-
-    public void setStudentId(Long studentId) {
-        this.studentId = studentId;
-    }
-
-    public String getSearch() {
-        return search;
-    }
-
-    public void setSearch(String search) {
-        this.search = search;
-    }
-
-    public Date getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(Date startTime) {
-        this.startTime = startTime;
-    }
-
-    public Date getEndTime() {
-        return endTime;
-    }
-
-    public void setEndTime(Date endTime) {
-        this.endTime = endTime;
-    }
+    @ApiModelProperty("客户端")
+    private String clientType;
 }

+ 7 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/OrderSearch.java

@@ -8,6 +8,7 @@ import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 /**
  * @Author: liweifan
@@ -22,7 +23,8 @@ public class OrderSearch extends QueryInfo{
 	@ApiModelProperty("下单应用:STUDENT 学生端 TEACHER 老师端")
 	private String orderClient;
 
-	@ApiModelProperty("交易类型:  VIP、开通会员  SVIP、开通会员 PRACTICE、趣纠课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名(多选用,分割)、VIP_COURSE VIP定制课、DISCOUNT 畅学卡")
+	@ApiModelProperty("交易类型:  VIP、开通会员  SVIP、开通会员 PRACTICE、趣纠课购买  LIVE、直播课购买 VIDEO、视频课购买 " +
+			"MUSIC、单曲点播 ACTI_REGIST、活动报名(多选用,分割)、VIP_COURSE VIP定制课、DISCOUNT 畅学卡、GROUP 小组课")
 	private String orderType;
 
 	@ApiModelProperty("订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭 FAIL 支付失败 (多选用,分割)")
@@ -51,6 +53,10 @@ public class OrderSearch extends QueryInfo{
 	@ApiModelProperty(hidden = true)
 	private String goodType;
 
+
+	@ApiModelProperty(hidden = true)
+	private List<String> goodTypes;
+
 	@ApiModelProperty(hidden = true)
 	private Long bizId;
 

+ 10 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseGroup.java

@@ -87,6 +87,10 @@ public class CourseGroup implements Serializable {
     @ApiModelProperty(value = "最少成课人数")
     private Integer mixStudentNum;
 
+    @TableField("max_student_num_")
+    @ApiModelProperty(value = "最大成课人数")
+    private Integer maxStudentNum;
+
     @TableField("pre_student_num_")
     @ApiModelProperty(value = "预计上课人数")
     private Integer preStudentNum;
@@ -123,5 +127,11 @@ public class CourseGroup implements Serializable {
     @ApiModelProperty(value = "更新时间")
     private Date updatedTime;
 
+
+    @TableField("lock_num_")
+    @ApiModelProperty(value = "小组课订单锁定数")
+    private Integer lockNum;
+
+
 }
 

+ 7 - 97
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentTime.java

@@ -9,11 +9,13 @@ import io.swagger.annotations.ApiModelProperty;
 import java.io.Serializable;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 
 /**
  * 学生使用功能时间表
  */
+@Data
 @TableName("student_time")
 @ApiModel(value = "StudentTime对象", description = "学生使用功能时间表")
 public class StudentTime implements Serializable {
@@ -26,6 +28,11 @@ public class StudentTime implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date firstVipTime;
 
+    @ApiModelProperty("第一次购买小组课时间 ")
+    @TableField(value = "first_group_time_")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date firstGroupTime;
 
     @ApiModelProperty("第一次购买svip时间 ")
     @TableField(value = "first_svip_time_")
@@ -88,101 +95,4 @@ public class StudentTime implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date firstDiscountTime;
 
-
-    public Date getFirstVipCourseTime() {
-        return firstVipCourseTime;
-    }
-
-    public void setFirstVipCourseTime(Date firstVipCourseTime) {
-        this.firstVipCourseTime = firstVipCourseTime;
-    }
-
-    public Date getFirstDiscountTime() {
-        return firstDiscountTime;
-    }
-
-    public void setFirstDiscountTime(Date firstDiscountTime) {
-        this.firstDiscountTime = firstDiscountTime;
-    }
-
-    public Date getFirstSvipTime() {
-        return firstSvipTime;
-    }
-
-    public void setFirstSvipTime(Date firstSvipTime) {
-        this.firstSvipTime = firstSvipTime;
-    }
-
-    public Date getFirstActivityTime() {
-        return firstActivityTime;
-    }
-
-    public void setFirstActivityTime(Date firstActivityTime) {
-        this.firstActivityTime = firstActivityTime;
-    }
-
-    public Date getFirstPayTime() {
-        return firstPayTime;
-    }
-
-    public void setFirstPayTime(Date firstPayTime) {
-        this.firstPayTime = firstPayTime;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public Date getFirstVipTime() {
-        return firstVipTime;
-    }
-
-    public void setFirstVipTime(Date firstVipTime) {
-        this.firstVipTime = firstVipTime;
-    }
-
-    public Date getFirstPracticeTime() {
-        return firstPracticeTime;
-    }
-
-    public void setFirstPracticeTime(Date firstPracticeTime) {
-        this.firstPracticeTime = firstPracticeTime;
-    }
-
-    public Date getFirstVideoTime() {
-        return firstVideoTime;
-    }
-
-    public void setFirstVideoTime(Date firstVideoTime) {
-        this.firstVideoTime = firstVideoTime;
-    }
-
-    public Date getFirstLiveTime() {
-        return firstLiveTime;
-    }
-
-    public void setFirstLiveTime(Date firstLiveTime) {
-        this.firstLiveTime = firstLiveTime;
-    }
-
-    public Date getFirstMusicTime() {
-        return firstMusicTime;
-    }
-
-    public void setFirstMusicTime(Date firstMusicTime) {
-        this.firstMusicTime = firstMusicTime;
-    }
-
-    public Date getFirstMallTime() {
-        return firstMallTime;
-    }
-
-    public void setFirstMallTime(Date firstMallTime) {
-        this.firstMallTime = firstMallTime;
-    }
-
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/AccountBizTypeEnum.java

@@ -25,9 +25,11 @@ public enum AccountBizTypeEnum implements BaseEnum<String, AccountBizTypeEnum> {
     TENANT_ALBUM("训练教程"),
     VIP_COURSE("VIP定制课"),
     DISCOUNT("畅学卡"),
+    GROUP("小组课"),
 
 
     LIVE_SHARE("直播课分润"),
+    GROUP_SHARE("小组课"),
     VIDEO_SHARE("视频课分润"),
     MUSIC_SHARE("乐谱分润"),
     ALBUM_SHARE("专辑分润"),

+ 3 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/CourseScheduleEnum.java

@@ -17,6 +17,8 @@ public enum CourseScheduleEnum implements BaseEnum<String, CourseScheduleEnum> {
     LIVE("直播课"),
     PIANO_ROOM_CLASS("琴房课"),
     VIP("VIP定制课"),
+    //小组课
+    GROUP("小组课"),
     //课程状态
     NOT_START("未开始"),
     ING("进行中"),
@@ -40,7 +42,7 @@ public enum CourseScheduleEnum implements BaseEnum<String, CourseScheduleEnum> {
      * @param errMsg 错误异常
      */
     public static CourseScheduleEnum existCourseType(String code, String errMsg) {
-        CourseScheduleEnum[] values = {PRACTICE, LIVE, PIANO_ROOM_CLASS,VIP};
+        CourseScheduleEnum[] values = {PRACTICE, LIVE, PIANO_ROOM_CLASS,VIP,GROUP};
         existCourse(values, code, errMsg);
         //返回枚举对象
         return CourseScheduleEnum.valueOf(code);

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

@@ -21,7 +21,8 @@ public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
     PIANO_ROOM("琴房时长"),
     ACTI_REGIST("活动报名"),
     VIP_COURSE("VIP定制课购买"),
-    DISCOUNT("畅学卡")
+    DISCOUNT("畅学卡"),
+    GROUP("小组课")
     ;
 
     @EnumValue

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java

@@ -30,10 +30,13 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
 
     TEACHER_DECORATE_HOMEWORK("老师布置作业"),
     TEACHER_DECORATE_HOMEWORK_VIP("老师布置作业"),
+    TEACHER_DECORATE_HOMEWORK_GROUP("老师布置作业"),
     TEACHER_REVIEW_HOMEWORK("老师点评作业"),
     TEACHER_REVIEW_HOMEWORK_VIP("老师点评作业"),
+    TEACHER_REVIEW_HOMEWORK_GROUP("老师点评作业"),
     STUDENT_SUBMIT_HOMEWORK("学员提交作业"),
     STUDENT_SUBMIT_HOMEWORK_VIP("学员提交作业"),
+    STUDENT_SUBMIT_HOMEWORK_GROUP("学员提交作业"),
 
     TEACHER_AUTH_PASS("达人认证通过"),
     SMS_TEACHER_AUTH_PASS("达人认证通过(短信)"),
@@ -58,13 +61,16 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     TOMORROW_COURSE_REMINDER("明日课程提醒(每晚9点)"),
     STUDENT_PRACTICE_REMINDER("趣纠课提醒(趣纠课开始前20分钟)"),
     STUDENT_VIP_REMINDER("VIP课提醒(VIP课开始前20分钟)"),
+    STUDENT_GROUP_REMINDER("小组课提醒(小组课开始前20分钟)"),
     LIVE_REMINDER("直播课提醒(直播课开始前20分钟)"),
     COURSE_SETTLEMENT("课酬结算(每晚9点)"),
     NOT_EVALUATE_STUDENT_PRACTICE("当日趣纠课未评价/布置作业(每晚9点30,已评价/已布置不发)"),
     STUDENT_EVALUATE_TEACHER_PRACTICE("学员对老师评价"),
     TEACHER_EVALUATE_STUDENT_PRACTICE("老师对学员评价"),
     STUDENT_EVALUATE_TEACHER_VIP("学员对老师评价"),
+    STUDENT_EVALUATE_TEACHER_GROUP("学员对老师评价"),
     TEACHER_EVALUATE_STUDENT_VIP("老师对学员评价"),
+    TEACHER_EVALUATE_STUDENT_GROUP("老师对学员评价"),
     WITHDRAWAL_SUCCESS("结算成功"),
     STUDENT_JOIN_FANSGROUP("学员申请加入粉丝群"),
     STUDENT_AUTOJOIN_FANSGROUP("学员自动加入粉丝群"),
@@ -90,6 +96,7 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     SMS_PRACTICE_BUY("趣纠课购买(短信)"),
 
     LIVE_BUY("直播课购买"),
+    GROUP_BUY("小组课购买"),
     SMS_LIVE_BUY("直播课购买"),
 
 
@@ -98,6 +105,7 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
 
     PRACTICE_REMIND("趣纠课提醒(趣纠课开始前20分钟)"),
     VIP_REMIND("VIP课提醒(VIP课开始前20分钟)"),
+    GROUP_REMIND("小组课提醒(小组课开始前20分钟)"),
     LIVE_REMIND("直播课提醒(直播课开始前20分钟)"),
     NOT_EVALUATE_TEACHER_PRACTICE("当日趣纠课未对老师评价(每晚9点,已评价不发)"),
     FANSGROUP_APPLY_SUCCESS("粉丝群申请通过"),
@@ -125,6 +133,7 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     PIANO_ROOM_ADJUST("琴房课调整"),
     PRACTICE_ADJUST("趣纠课调整"),
     VIP_ADJUST("VIP课调整"),
+    GROUP_ADJUST("小组课调整"),
     ACTIVITY_WIN("获奖消息"),
     PLATFORM_ADD_VIP("会员赠送"),
     PLATFORM_ADD_SVIP("会员赠送"),
@@ -170,7 +179,12 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     //老师修改课程规划
     TEACHER_UPDATE_COURSE_PLAN("老师修改课程规划"),
     TEACHER_UPDATE_COURSE_PLAN_VIP("老师修改课程规划"),
+    TEACHER_UPDATE_COURSE_PLAN_GROUP("老师修改课程规划"),
     TEACHER_UPDATE_COURSE_PLAN_PIANO_ROOM_CLASS("老师修改课程规划"),
+    GROUP_SUCCESS_STUDENT("小组课已成课"),
+    GROUP_SUCCESS_TEACHER("小组课已成课"),
+    GROUP_FAIL_STUDENT("小组课成课失败"),
+    GROUP_FAIL_TEACHER("小组课成课失败"),
     ;
 
     MessageTypeEnum(String msg) {

+ 2 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/OrderTypeEnum.java

@@ -21,7 +21,8 @@ public enum OrderTypeEnum implements BaseEnum<String, OrderTypeEnum> {
     ALBUM("专辑购买"),
     TENANT_ALBUM("平台专辑"),
     VIP_COURSE("VIP定制课"),
-    DISCOUNT("畅学卡")
+    DISCOUNT("畅学卡"),
+    GROUP("小组课购买")
     ;
     @EnumValue
     private String code;

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

@@ -26,6 +26,7 @@ public enum CouponCategoryEnum implements BaseEnum<String, CouponCategoryEnum> {
     VIDEO("视频课购买券", "VIDEO"),
     VIP_COURSE("VIP定制课购买券", "VIP_COURSE"),
     DISCOUNT("畅学卡","DISCOUNT"),
+    GROUP("小组课优惠券","GROUP"),
     ;
 
     @EnumValue

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

@@ -16,6 +16,7 @@ public enum CourseTypeEnum implements BaseEnum<String, CourseTypeEnum> {
     PIANO_ROOM_CLASS("琴房课"),
     VIDEO("视频课"),
     VIP("VIP定制课"),
+    GROUP("小组课"),
     ;
     @EnumValue
     private String code;

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

@@ -44,6 +44,13 @@ public interface CourseGroupService extends IService<CourseGroup> {
     LiveCourseInfoVo queryLiveCourseInfo(Long groupId);
 
     /**
+     * 查询课程组详情
+     *
+     * @param groupId 课程组id
+     */
+    CourseInfoVo queryCourseInfo(Long groupId);
+
+    /**
      * 分页查询课程组列表
      *
      * @param param 传入参数
@@ -379,5 +386,7 @@ public interface CourseGroupService extends IService<CourseGroup> {
     List<CourseGroupWrapper.CourseStudentVo> queryStudentByGroupId(Long groupId);
 
     void updateCoursePlan(Long groupId, String coursePlan);
+
+    void buyGroupSendMessage(CourseScheduleStudentPayment studentPayment, CourseGroup courseGroup);
 }
 

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserOrderRefundBillService.java

@@ -6,6 +6,8 @@ import com.yonge.cooleshow.biz.dal.vo.UserOrderRefundBillVo;
 import com.yonge.cooleshow.biz.dal.dto.search.UserOrderRefundPaymentSearch;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
 
+import java.util.List;
+
 /**
  * 退款单表 服务类
  * @author liweifan
@@ -28,4 +30,6 @@ public interface UserOrderRefundBillService extends IService<UserOrderRefundBill
     IPage<UserOrderRefundBillVo> selectPage(IPage<UserOrderRefundBillVo> page, UserOrderRefundPaymentSearch query);
 
     UserOrderRefundBill getByTransNoOrOrderNo(String transNo, String refundOrderNo);
+
+    List<UserOrderRefundBill> getPendingList();
 }

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

@@ -11,6 +11,7 @@ import com.yonge.cooleshow.biz.dal.entity.UserOrderRefundBill;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderRefundVo;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
 
@@ -87,4 +88,6 @@ public interface UserOrderRefundService extends IService<UserOrderRefund>  {
 	void orderRefundSuccessBizHandle(Long refundId);
 
     void orderRefundSuccessBizHandleByOrderNo(String orderNo, List<Long> orderDetailIds);
+
+	List<UserOrderRefund> getByOrderNo(String orderNo, @NotNull List<Long> orderDetailIds);
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserPaymentCoreService.java

@@ -112,4 +112,6 @@ public interface UserPaymentCoreService {
      * @param orderNo 订单编号
      */
     void paymentStatus(String orderNo);
+
+    void scanRefundOrderRecord();
 }

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

@@ -110,6 +110,9 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     private CouponInfoService couponInfoService;
 
     @Autowired
+    private CourseGroupDao courseGroupDao;
+
+    @Autowired
     private PlatformCashAccountRecordService platformCashAccountRecordService;
 
     @Autowired
@@ -132,6 +135,11 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         return queryLiveCourseInfo(groupId, sysUserService.getUser());
     }
 
+    @Override
+    public CourseInfoVo queryCourseInfo(Long groupId) {
+        return queryCourseInfo(groupId, sysUserService.getUser());
+    }
+
     /**
      * 查询课程组详情-直播课详情
      *
@@ -144,6 +152,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
         LiveCourseInfoVo result = new LiveCourseInfoVo();
         result.setCourseGroupId(group.getId());
+        result.setType(group.getType());
+        result.setCourseGroupId(group.getId());
         result.setCourseGroupName(group.getName());
         result.setCourseStartTime(group.getCourseStartTime());
         result.setSingleCourseMinutes(group.getSingleCourseMinutes());
@@ -202,6 +212,71 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //因为页面再点击购买按钮时,会请求/userOrder/getPendingOrder接口,如果有支付中的订单,用户选择继续支付或取消订单
         OrderSearch query = new OrderSearch();
         query.setUserId(id);
+        query.setGoodTypes(Lists.newArrayList(group.getType()));
+        query.setBizId(groupId);
+        query.setStatus(OrderStatusEnum.PAID.getCode());
+        List<UserOrderVo> userOrderVos = userOrderService.selectAllList(query);
+        if (CollectionUtils.isNotEmpty(userOrderVos)) {
+            result.setExistBuy(1);
+        }else {
+            result.setExistBuy(0);
+            if(StringUtils.equals("GROUP",group.getType()) && Objects.equals(group.getMaxStudentNum(), group.getPreStudentNum())){
+                result.setExistBuy(2);
+            }
+        }
+        return result;
+    }
+    private CourseInfoVo queryCourseInfo(Long groupId, SysUser sysUser) {
+        CourseGroup group = Optional.ofNullable(groupId).map(this::getById)
+                .orElseThrow(() -> new BizException("课程组信息不存在"));
+
+        CourseInfoVo result = new CourseInfoVo();
+        result.setCourseGroupId(group.getId());
+        result.setCourseGroupName(group.getName());
+        result.setCourseStartTime(group.getCourseStartTime());
+        result.setSingleCourseMinutes(group.getSingleCourseMinutes());
+        result.setStatus(group.getStatus());
+        result.setStudentCount(group.getPreStudentNum());
+        result.setBackgroundPic(group.getBackgroundPic());
+        result.setTeacherId(group.getTeacherId());
+        result.setCoursePrice(group.getCoursePrice());
+        result.setCourseNum(group.getCourseNum());
+        result.setCompleteCourseNum(group.getCompleteCourseNum());
+        result.setCourseIntroduce(group.getCourseIntroduce());
+        result.setSalesStartDate(group.getSalesStartDate());
+        result.setSalesEndDate(group.getSalesEndDate());
+        result.setMixStudentNum(group.getMixStudentNum());
+        result.setMaxStudentNum(group.getMaxStudentNum());
+        result.setImGroupId(group.getImGroupId());
+        result.setAuditVersion(group.getAuditVersion());
+        SysUser teacherUser = sysUserService.getByUserId(group.getTeacherId());
+        if (teacherUser == null) {
+            throw new BizException("用户不存在");
+        }
+        if (sysUser.getId().equals(teacherUser.getId())) {
+            result.setMyself(true);
+        } else {
+            result.setMyself(false);
+        }
+        Teacher teacher = teacherService.getById(teacherUser.getId());
+
+        if (teacher != null) {
+            result.setDegreeFlag(teacher.getDegreeFlag());
+            result.setTeacherFlag(teacher.getTeacherFlag());
+
+        }
+        result.setTeacherName(teacherUser.getRealName());
+        result.setUserName(teacherUser.getUsername());
+        result.setAvatar(teacherUser.getAvatar());
+        Optional.ofNullable(group.getSubjectId()).map(subjectService::get)
+                .ifPresent(subject -> result.setSubjectName(subject.getName()));
+        //查询是否购买过该课程组
+        Long id = sysUser.getId();
+
+        //这里修改为,订单完成后才算购买过,待支付和支付中订单不算
+        //因为页面再点击购买按钮时,会请求/userOrder/getPendingOrder接口,如果有支付中的订单,用户选择继续支付或取消订单
+        OrderSearch query = new OrderSearch();
+        query.setUserId(id);
         query.setGoodType(GoodTypeEnum.LIVE.getCode());
         query.setBizId(groupId);
         query.setStatus(OrderStatusEnum.PAID.getCode());
@@ -225,7 +300,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
      */
     public PageInfo<CourseGroupVo> queryPageLiveCourseGroup(Map<String, Object> param) {
         //查询该月的所有直播课程
-        param.put("type", CourseScheduleEnum.LIVE.getCode());
+        param.put("type", param.get("courseType") == null?CourseScheduleEnum.LIVE.getCode():param.get("courseType").toString());
         Page<CourseGroupVo> pageInfo = PageUtil.getPageInfo(param);
         pageInfo.setAsc("b.created_time_");
         String os = WrapperUtil.toStr(param, "os");
@@ -263,10 +338,10 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         });
         cacheTime.fastPut(dto.getTeacherId(), timeEntities);
         Date now = new Date();
-        String live = CourseScheduleEnum.LIVE.getCode();
+        String courseType = dto.getCourseType();
         //写入课程组表
         CourseGroup group = new CourseGroup();
-        group.setType(live);
+        group.setType(courseType);
         group.setTeacherId(dto.getTeacherId());
         group.setName(dto.getName());
         group.setSubjectId(dto.getSubjectId());
@@ -280,6 +355,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         group.setSalesEndDate(dto.getSalesEndDate());
         group.setBackgroundPic(dto.getBackgroundPic());
         group.setMixStudentNum(dto.getMixStudentNum());
+        group.setMaxStudentNum(dto.getMaxStudentNum());
         group.setCreatedBy(dto.getTeacherId());
         group.setCreatedTime(now);
         this.save(group);
@@ -290,7 +366,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         dto.getCoursePlanList().forEach(o -> {
             CourseSchedule course = new CourseSchedule();
             course.setCourseGroupId(group.getId());
-            course.setType(live);
+            course.setType(courseType);
             course.setClassNum(o.getClassNum());
             course.setTeacherId(dto.getTeacherId());
             course.setClassDate(o.getStartTime());
@@ -361,7 +437,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //课程组信息
         CourseGroup courseGroup = this.getOne(Wrappers.<CourseGroup>lambdaQuery()
                 .eq(CourseGroup::getId, groupId)
-                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+                .eq(CourseGroup::getType, orderGoodsInfo.getGoodType().name())
         );
         if (Objects.isNull(courseGroup)) {
             throw new BizException("课程组不存在!");
@@ -379,6 +455,10 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //校验购买的课程组每节课时间是否和自己的课时冲突
         batchCheckStudentCourseTime(studentId, courseList, CourseSchedule::getStartTime, CourseSchedule::getEndTime);
 
+        // 小组课判断购买人数
+        if (orderGoodsInfo.getGoodType() == GoodTypeEnum.GROUP && courseGroup.getLockNum()>=courseGroup.getMaxStudentNum()) {
+            throw new BizException("小组课已满员!");
+        }
 
 
         UserOrderDetail userOrderDetail = JSON.parseObject(JSON.toJSONString(orderGoodsInfo), UserOrderDetail.class);
@@ -418,7 +498,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(userIds);
             for (CourseGroupWrapper.TeacherCourseGroupDto e : records) {
                 e.setSubjectName(subjectMap.get(e.getSubjectId()));
-                if(StringUtils.equals(query.getCourseType(),"PIANO_ROOM_CLASS")){
+                if(StringUtils.equals(query.getCourseType(),"PIANO_ROOM_CLASS") || StringUtils.equals(query.getCourseType(),"GROUP")){
                     List<CourseScheduleStudentPayment> studentPayments = map.get(e.getCourseGroupId());
                     if(CollectionUtils.isNotEmpty(studentPayments)){
                         List<Long> studentIds = studentPayments.stream().map(CourseScheduleStudentPayment::getUserId).distinct().collect(Collectors.toList());
@@ -528,6 +608,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                     messageType = MessageTypeEnum.TEACHER_UPDATE_COURSE_PLAN_VIP;
                 }else if (CourseTypeEnum.valueOf(courseGroup.getType()) == CourseTypeEnum.PIANO_ROOM_CLASS){
                     messageType = MessageTypeEnum.TEACHER_UPDATE_COURSE_PLAN_PIANO_ROOM_CLASS;
+                }else if (CourseTypeEnum.valueOf(courseGroup.getType()) == CourseTypeEnum.GROUP){
+                    messageType = MessageTypeEnum.TEACHER_UPDATE_COURSE_PLAN_GROUP;
                 }
                 sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
                         messageType,
@@ -541,6 +623,26 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         }
     }
 
+    @Override
+    public void buyGroupSendMessage(CourseScheduleStudentPayment studentPayment, CourseGroup courseGroup) {
+        //查询老师信息
+        SysUser teacherInfo = sysUserService.findUserById(courseGroup.getTeacherId());
+        //查询学生信息
+        SysUser studentInfo = sysUserService.findUserById(studentPayment.getUserId());
+        try {
+
+            //极光-消息推送-学生端-通知学生购买成功-跳转到APP
+            MessageTypeEnum liveBuy = MessageTypeEnum.GROUP_BUY;
+            Map<Long, String> studentReceivers = new HashMap<>();
+            studentReceivers.put(studentInfo.getId(), studentInfo.getPhone());
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, liveBuy,
+                    studentReceivers, null, 0, "", ClientEnum.STUDENT.getCode(),
+                    teacherInfo.getUsername(), courseGroup.getName());
+        } catch (Exception ex) {
+            log.error("buyGroupSendMessage error", ex.getCause());
+        }
+    }
+
     /**
      *
      * 直播课购买后数据写入
@@ -555,7 +657,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         //课程组信息
         CourseGroup courseGroup = this.getOne(Wrappers.<CourseGroup>lambdaQuery()
                 .eq(CourseGroup::getId, groupId)
-                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+                .eq(CourseGroup::getType, orderGoodsInfo.getGoodType().name())
         );
         if (Objects.isNull(courseGroup)) {
             throw new BizException("课程组不存在!");
@@ -570,6 +672,19 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         if (CollectionUtils.isEmpty(courseList)) {
             throw new BizException("课程组课程不存在!");
         }
+
+        // 小组课判断购买人数
+        if (orderGoodsInfo.getGoodType() == GoodTypeEnum.GROUP ) {
+            if (courseGroup.getLockNum() >= courseGroup.getMaxStudentNum()) {
+                throw new BizException("小组课已满员!");
+            }
+            // 更新小组课锁定人数
+            int i = courseGroupDao.updateLockNum(groupId, 1);
+            if (i == 0) {
+                throw new BizException("小组课已满员!");
+            }
+        }
+
         // 写入学生购买课程记录 换到订单写入成功后写入
         buyLiveCourseAfter(orderGoodsInfo.getOrderNo(), orderGoodsInfo.getUserId(), courseList,
                 courseGroup,orderGoodsInfo.getUserOrderDetail().getActualPrice());
@@ -619,7 +734,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             coursePlanDto.setFreeEndTime(DateUtil.offsetMinute(coursePlanDto.getEndTime(), dto.getCourseFreeMinutes()));
         }
         // true:趣纠课PRACTICE     false:LIVE直播课
-        boolean courseTypeFlag = Lists.newArrayList(CourseScheduleEnum.PRACTICE,CourseScheduleEnum.VIP).contains(CourseScheduleEnum.existCourseType(dto.getCourseType(), "课程类型不正确!"));
+        boolean courseTypeFlag = Lists.newArrayList(CourseScheduleEnum.PRACTICE,CourseScheduleEnum.VIP)
+                .contains(CourseScheduleEnum.existCourseType(dto.getCourseType(), "课程类型不正确!"));
         //先自校验传入时间是否交集
         List<CourseTimeEntity> timeList = dto.getTimeList();
         if (CollectionUtils.isEmpty(timeList)) {
@@ -1181,7 +1297,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             Map<Long, String> smsStudentReceivers = new HashMap<>();
             smsStudentReceivers.put(studentInfo.getId(), studentInfo.getPhone());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, smsLiveBuy,
-                    smsStudentReceivers, null, 0, null,payType,
+                    smsStudentReceivers, null, 0, null,ClientEnum.STUDENT.getCode(),payType,
                     teacherInfo.getUsername(), courseGroup.getName());
             log.info("buyLiveCourseSuccess buyLiveSendMessage SMS_BUY_LIVE ok");
 
@@ -1233,6 +1349,12 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     public void buyLiveCourseCancel(UserOrderDetailVo orderParam) {
         courseScheduleStudentPaymentService.remove(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
                 .eq(CourseScheduleStudentPayment::getOrderNo, orderParam.getOrderNo()));
+
+
+        if (orderParam.getGoodType() == GoodTypeEnum.GROUP ) {
+            // 减少订单锁定
+            courseGroupDao.updateLockNum(orderParam.getBizId(), -1);
+        }
     }
 
     /**
@@ -1371,7 +1493,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         LocalDate yesterday = today.plusDays(-1L);
         //查询今天未开售的课程组
         List<CourseGroup> courseGroupList = this.list(Wrappers.<CourseGroup>lambdaQuery()
-                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+                .in(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode(),CourseScheduleEnum.GROUP.getCode())
                 .ge(CourseGroup::getSalesStartDate, yesterday)
                 .le(CourseGroup::getSalesStartDate, today)
                 .eq(CourseGroup::getStatus, CourseGroupEnum.NOT_SALE.getCode()));
@@ -1396,7 +1518,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     private void closeCourseGroup() {
         //查询昨天要结束售卖的课程组
         List<CourseGroup> courseGroupList = this.list(Wrappers.<CourseGroup>lambdaQuery()
-                .eq(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode())
+                .in(CourseGroup::getType, CourseScheduleEnum.LIVE.getCode(),CourseScheduleEnum.GROUP.getCode())
                 .eq(CourseGroup::getSalesEndDate, LocalDate.now().plusDays(-1))
                 .in(CourseGroup::getStatus, CourseGroupEnum.APPLY.getCode(),CourseGroupEnum.OUT_SALE.getCode()));
         if (CollectionUtils.isEmpty(courseGroupList)) {
@@ -1423,6 +1545,12 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                     //添加老师进群
                     imGroupMemberService.initGroupMembers(imGroupId, Collections.singleton(courseGroup.getTeacherId()), ImGroupMemberRoleType.TEACHER);
                     courseGroup.setImGroupId(imGroupId);
+
+                    // 小组课成课推送
+                    if (courseGroup.getType().equals(CourseScheduleEnum.GROUP.getCode())) {
+                        // 极光-消息推送-老师端-通知老师小组课程组成课
+                        sendGroupSuccessMessage(courseGroup,true);
+                    }
                 } else {
                     //人数未达标则修改课程组为取消状态
                     courseGroup.setStatus(CourseGroupEnum.CANCEL.getCode());
@@ -1431,14 +1559,23 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                             .eq(CourseSchedule::getCourseGroupId, courseGroup.getId())
                             .set(CourseSchedule::getStatus, CourseScheduleEnum.CANCEL.getCode())
                     );
-                    // 老师直播课成课失败发送消息
-                    this.sendMessage(courseGroup);
-
-                    // 学生直播课成课失败发送消息
-                    this.sendStudentMessage(userIds,courseGroup);
 
                     //退款
                     this.refund(courseGroup);
+
+                    // 小组课成课推送
+                    if (courseGroup.getType().equals(CourseScheduleEnum.GROUP.getCode())) {
+
+                        // 极光-消息推送-老师端-通知老师小组课程组成课
+                        sendGroupSuccessMessage(courseGroup,false);
+                    } else {
+                        // 老师直播课成课失败发送消息
+                        this.sendMessage(courseGroup);
+
+                        // 学生直播课成课失败发送消息
+                        this.sendStudentMessage(userIds, courseGroup);
+                    }
+
                 }
                 courseGroup.setUpdatedTime(new Date());
                 this.updateById(courseGroup);
@@ -1449,6 +1586,37 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         });
     }
 
+    private void sendGroupSuccessMessage(CourseGroup courseGroup,boolean success) {
+        // 老师
+        SysUser sysUser = sysUserService.getByUserId(courseGroup.getTeacherId());
+        try {
+            Map<Long, String> receivers = new HashMap<>();
+            receivers.put(sysUser.getId(), sysUser.getPhone());
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, success?MessageTypeEnum.GROUP_SUCCESS_TEACHER:MessageTypeEnum.GROUP_FAIL_TEACHER,
+                    receivers, null, 0, null, ClientEnum.TEACHER.getCode(), courseGroup.getName());
+        } catch (Exception e) {
+            log.warn("小组课成课成功推送发送失败,{}", e.getMessage());
+        }
+
+
+        try {
+            List<CourseScheduleStudentPayment> list = courseScheduleStudentPaymentService.list(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
+                    .eq(CourseScheduleStudentPayment::getCourseGroupId, courseGroup.getId()));
+            Set<Long> userIds = list.stream().map(CourseScheduleStudentPayment::getUserId).collect(Collectors.toSet());
+            // 学生
+            Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> mapByIds = sysUserService.getMapByIds(new ArrayList<>( userIds));
+
+            Map<Long, String> receivers = new HashMap<>();
+            for (com.yonge.cooleshow.biz.dal.entity.SysUser value : mapByIds.values()) {
+                receivers.put(value.getId(), value.getPhone());
+            }
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, success?MessageTypeEnum.GROUP_SUCCESS_STUDENT:MessageTypeEnum.GROUP_FAIL_STUDENT,
+                    receivers, null, 0, null, ClientEnum.STUDENT.getCode(), courseGroup.getName());
+        } catch (Exception e) {
+            log.warn("小组课成课成功推送发送失败,{}", e.getMessage());
+        }
+    }
+
     private void sendStudentMessage(Set<Long> userIds, CourseGroup courseGroup) {
         for (Long userId : userIds) {
 
@@ -1497,14 +1665,15 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
                 List<Long> orderDetailIds = new ArrayList<>();
                 if (CollectionUtils.isNotEmpty(detail.getOrderDetailList())) {
-                    detail.getOrderDetailList().stream().filter(orderDetail -> orderDetail.getGoodType() == GoodTypeEnum.LIVE)
+                    detail.getOrderDetailList().stream()
+                            .filter(orderDetail -> orderDetail.getGoodType() == GoodTypeEnum.LIVE || orderDetail.getGoodType() == GoodTypeEnum.GROUP)
                             .filter(orderDetail -> orderDetail.getBizId().equals(courseGroup.getId()))
                             .forEach(orderDetail -> orderDetailIds.add(orderDetail.getId()));
                 }
                 if (order.getPaymentVersion().equals(EPaymentVersion.V1)) {
-                    userOrderRefundService.orderRefund(order.getOrderNo(), "直播课成课失败退款");
+                    userOrderRefundService.orderRefund(order.getOrderNo(), CourseScheduleEnum.valueOf(courseGroup.getType()).getMsg() +"成课失败退款");
                 } else {
-                    userPaymentCoreService.refundPayment(order.getOrderNo(),"直播课成课失败退款", orderDetailIds);
+                    userPaymentCoreService.refundPayment(order.getOrderNo(),CourseScheduleEnum.valueOf(courseGroup.getType()).getMsg() +"成课失败退款", orderDetailIds);
                 }
 
                 //退还优惠券
@@ -1512,8 +1681,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                     couponInfoService.updateUserOrderCouponInfo(CouponOrderWrapper.builder().orderNo(order.getOrderNo()).reset(true).build());
                 }
             } catch (Exception e) {
-                log.warn("直播课成课失败退款 退款失败,退款订单号 {}", order);
-                log.error("直播课成课失败退款 退款失败", e);
+                log.warn("成课失败退款 退款失败,退款订单号 {}", order);
+                log.error("成课失败退款 退款失败", e);
             }
         }
     }
@@ -1652,7 +1821,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
         ShareProfitVo result = new ShareProfitVo();
         result.setTeacherId(sysUser.getId());
-        result.setType("LIVE");
+        result.setType(liveCourseInfoVo.getType());
         result.setLiveCourseGroup(liveCourseGroupShareVo);
         result.setUrl(MessageFormatter.arrayFormat(teacherLiveGroupShareProfitUrl, liveGroupId, sysUser.getId()));
         result.setName(sysUser.getUsername());
@@ -1677,7 +1846,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             throw new BizException("只能下架销售中的课程组");
         } else if (dto.getStatus() == 1  && !CourseGroupEnum.OUT_SALE.getCode().equals(liveCourseGroupVo.getStatus())) {
             throw new BizException("只能上架被下架的课程组");
-        } else if ( LocalDate.now().compareTo(liveCourseGroupVo.getSalesEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) > 0) {
+        } else if (LocalDate.now().isAfter(liveCourseGroupVo.getSalesEndDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate())) {
             throw new BizException("课程组售卖时间已结束,不能操作");
         }
 

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

@@ -282,6 +282,8 @@ public class CourseHomeworkServiceImpl extends ServiceImpl<CourseHomeworkDao, Co
         MessageTypeEnum messageType = MessageTypeEnum.TEACHER_DECORATE_HOMEWORK;
         if(CourseTypeEnum.valueOf(courseSchedule.getType()) == CourseTypeEnum.VIP){
             messageType = MessageTypeEnum.TEACHER_DECORATE_HOMEWORK_VIP;
+        }else if(CourseTypeEnum.valueOf(courseSchedule.getType()) == CourseTypeEnum.GROUP){
+            messageType = MessageTypeEnum.TEACHER_DECORATE_HOMEWORK_GROUP;
         }
         SysUser teacher = sysUserFeignService.queryUserById(courseSchedule.getTeacherId());
 //        String url = sysMessageService.selectConfigUrl(MessageTypeEnum.TEACHER_DECORATE_HOMEWORK.getCode(),courseSchedule.getId());
@@ -363,6 +365,8 @@ public class CourseHomeworkServiceImpl extends ServiceImpl<CourseHomeworkDao, Co
         MessageTypeEnum messageType = MessageTypeEnum.TEACHER_REVIEW_HOMEWORK;
         if(courseHomeworkDetailVo.getCourseType() == CourseScheduleEnum.VIP){
             messageType = MessageTypeEnum.TEACHER_REVIEW_HOMEWORK_VIP;
+        }else if(courseHomeworkDetailVo.getCourseType() == CourseScheduleEnum.GROUP){
+            messageType = MessageTypeEnum.TEACHER_REVIEW_HOMEWORK_GROUP;
         }
         studentReceivers.put(student.getId(), student.getPhone());
 //        String url = sysMessageService.selectConfigUrl(MessageTypeEnum.TEACHER_REVIEW_HOMEWORK.getCode(),reviewDto.getCourseScheduleId());

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

@@ -130,6 +130,8 @@ public class CourseRepliedServiceImpl extends ServiceImpl<CourseScheduleRepliedD
             MessageTypeEnum messageType = MessageTypeEnum.TEACHER_EVALUATE_STUDENT_PRACTICE;
             if(courseTypeEnum == CourseTypeEnum.VIP){
                 messageType = MessageTypeEnum.TEACHER_EVALUATE_STUDENT_VIP;
+            }else if (courseTypeEnum == CourseTypeEnum.GROUP){
+                messageType = MessageTypeEnum.TEACHER_EVALUATE_STUDENT_GROUP;
             }
 //            String url = sysMessageService.selectConfigUrl(MessageTypeEnum.TEACHER_EVALUATE_STUDENT_PRACTICE.getCode());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
@@ -151,6 +153,8 @@ public class CourseRepliedServiceImpl extends ServiceImpl<CourseScheduleRepliedD
         MessageTypeEnum messageType = MessageTypeEnum.STUDENT_EVALUATE_TEACHER_PRACTICE;
         if(courseTypeEnum == CourseTypeEnum.VIP){
             messageType = MessageTypeEnum.STUDENT_EVALUATE_TEACHER_VIP;
+        }else if (courseTypeEnum == CourseTypeEnum.GROUP){
+            messageType = MessageTypeEnum.STUDENT_EVALUATE_TEACHER_GROUP;
         }
         try {
             SysUser student = sysUserFeignService.queryUserById(studentId);

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

@@ -54,6 +54,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
@@ -149,6 +150,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
     private TeacherAttendanceService teacherAttendanceService;
     @Autowired
     private SubjectService subjectService;
+    @Resource
+    private CoursePlanService coursePlanService;
 
     @Override
     public CourseScheduleDao getDao() {
@@ -172,7 +175,6 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         }
         param.put("status", status);
         param.put("teacherId", sysUserService.getUserId());
-        param.put("type", CourseScheduleEnum.LIVE.getCode());
         param.put("groupState", String.join(",", CourseGroupEnum.ING.getCode(), CourseGroupEnum.COMPLETE.getCode()));
         log.info("queryTeacherLiveCourse:{}", param);
         Page<TeacherLiveCourseInfoVo> pageInfo = PageUtil.getPageInfo(param);
@@ -1035,6 +1037,10 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
     @NotNull
     private Map<String, String> getCourseJoinMap() {
         Map<String, String> sysConfig = new HashMap<>();
+        //提前XX分钟创建/进入GROUP课房间时间
+        sysConfig.put("groupStartTime", sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_GROUP_ROOM_MINUTE));
+        //GROUP课结束后,XX分钟关闭房间
+        sysConfig.put("groupEndTime", sysConfigService.findConfigValue(SysConfigConstant.DESTROY_EXPIRED_GROUP_ROOM_MINUTE));
         //提前XX分钟创建/进入VIP课房间时间
         sysConfig.put("vipStartTime", sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_VIP_ROOM_MINUTE));
         //VIP课结束后,XX分钟关闭房间
@@ -1089,23 +1095,9 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                 item.setImUserId(imGroupService.getImUserId(String.valueOf(item.getUserId()),ClientEnum.TEACHER.name()));
             }
         }
-
-        Map<String, String> sysConfig = new HashMap<>();
-        //提前XX分钟创建/进入趣纠课房间时间
-        sysConfig.put("practiceStartTime", sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_PRACTICE_ROOM_MINUTE));
-        //趣纠课结束后,XX分钟关闭房间
-        sysConfig.put("practiceEndTime", sysConfigService.findConfigValue(SysConfigConstant.DESTROY_EXPIRED_PRACTICE_ROOM_MINUTE));
-        //提前XX分钟创建/进入直播房间的时间
-        sysConfig.put("liveStartTime", sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_LIVE_ROOM_MINUTE));
-        //直播结束后,XX分钟关闭房间
-        sysConfig.put("liveEndTime", sysConfigService.findConfigValue(SysConfigConstant.DESTROY_EXPIRED_LIVE_ROOM_MINUTE));
-        //提前XX分钟创建/进入琴房课房间时间
-        sysConfig.put("pianoStartTime", sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_PIANO_ROOM_MINUTE));
-        //琴房课结束后,XX分钟关闭房间
-        sysConfig.put("pianoEndTime", sysConfigService.findConfigValue(SysConfigConstant.DESTROY_EXPIRED_PIANO_ROOM_MINUTE));
-
+        Map<String, String> courseJoinMap = getCourseJoinMap();
         Map map = new HashMap();
-        map.put("sysConfig", sysConfig);
+        map.put("sysConfig", courseJoinMap);
         map.put("studentList", teacherList);
         return map;
     }
@@ -1122,8 +1114,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
     @Override
     public PageInfo<CourseStudent> queryStudentLiveCourse(Map<String, Object> param) {
         //本月的最后一天
-        param.put("type", CourseScheduleEnum.LIVE.getCode());
         param.put("orderState", OrderStatusEnum.PAID.getCode());
+        param.put("groupState", String.join(",", CourseGroupEnum.ING.getCode(), CourseGroupEnum.COMPLETE.getCode()));
         Page<CourseStudent> pageInfo = PageUtil.getPageInfo(param);
         return PageUtil.pageInfo(baseMapper.queryStudentLiveCourse(pageInfo, param));
     }
@@ -1451,8 +1443,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         CourseSchedule schedule = baseMapper.selectOne(Wrappers.<CourseSchedule>lambdaQuery()
                 .eq(CourseSchedule::getId, courseId)
                 .eq(CourseSchedule::getLock, 0)
-                .eq(CourseSchedule::getStatus, CourseScheduleEnum.NOT_START)
-                .in(CourseSchedule::getType, CourseScheduleEnum.PRACTICE, CourseScheduleEnum.VIP));
+                .eq(CourseSchedule::getStatus, CourseScheduleEnum.NOT_START));
         if (ObjectUtil.isEmpty(schedule)) {
             throw new BizException("无法调整该课程,课程不存在");
         }
@@ -1469,8 +1460,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
 
         //查询是否有人购买
         CourseScheduleStudentPayment studentPayment = paymentDao.selectOne(Wrappers.<CourseScheduleStudentPayment>lambdaQuery()
-                .eq(CourseScheduleStudentPayment::getCourseId, courseId)
-                .in(CourseScheduleStudentPayment::getCourseType, CourseScheduleEnum.PRACTICE,CourseScheduleEnum.VIP));
+                .eq(CourseScheduleStudentPayment::getCourseId, courseId));
         if (ObjectUtil.isEmpty(studentPayment)) {
             throw new BizException("课程无人购买");
         }
@@ -1524,6 +1514,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             MessageTypeEnum messageType = MessageTypeEnum.PRACTICE_ADJUST;
             if(CourseTypeEnum.valueOf(courseGroup.getType()) == CourseTypeEnum.VIP){
                 messageType = MessageTypeEnum.VIP_ADJUST;
+            }else if(CourseTypeEnum.valueOf(courseGroup.getType()) == CourseTypeEnum.GROUP){
+                messageType = MessageTypeEnum.GROUP_ADJUST;
             }
             Map<Long, String> receivers = new HashMap<>();
             receivers.put(studentId, student.getPhone());
@@ -1567,7 +1559,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             StudentHomePage.RecentCourses recentCourses = baseMapper.selectRecentCourses(studentId);
 
             if (recentCourses !=null &&
-                    (CourseScheduleEnum.PRACTICE.getCode().equals(recentCourses.getCourseType()) || CourseScheduleEnum.VIP.getCode().equals(recentCourses.getCourseType()))) {
+                    (CourseScheduleEnum.PRACTICE.getCode().equals(recentCourses.getCourseType())
+                            || CourseScheduleEnum.VIP.getCode().equals(recentCourses.getCourseType()))) {
                 SysUser sysUser = sysUserService.getByUserId(studentId);
                 if (sysUser != null) {
                     recentCourses.setCourseGroupName(recentCourses.getCourseGroupName() + "-" + sysUser.getUsername());
@@ -1578,7 +1571,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (studentId == null) {
             //vip课和趣纠课
             StudentHomePage.RecentCourses coursesPractice = baseMapper.selectRecentCoursesPractice(teacherId);
-            StudentHomePage.RecentCourses coursesLive = baseMapper.selectRecentCoursesLive(teacherId);//直播课&琴房课共用coursesLive
+            StudentHomePage.RecentCourses coursesLive = baseMapper.selectRecentCoursesLive(teacherId);//直播课&琴房课&小组课共用coursesLive
 
             if (coursesPractice == null && coursesLive != null) {
                 homePage.setRecentCourses(coursesLive);
@@ -1599,7 +1592,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             // 本周未上课程数
 
             if (coursesPractice != null &&
-                    (CourseScheduleEnum.PRACTICE.getCode().equals(coursesPractice.getCourseType()) || CourseScheduleEnum.VIP.getCode().equals(coursesPractice.getCourseType()))) {
+                    (CourseScheduleEnum.PRACTICE.getCode().equals(coursesPractice.getCourseType())
+                            || CourseScheduleEnum.VIP.getCode().equals(coursesPractice.getCourseType()))) {
                 SysUser sysUser = sysUserService.getByUserId(coursesPractice.getStudentId());
                 if (sysUser != null) {
                     coursesPractice.setCourseGroupName(coursesPractice.getCourseGroupName() + "-" + sysUser.getUsername());
@@ -1628,6 +1622,9 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                 case "VIP":
                     start= Integer.parseInt(courseJoinMap.get("vipStartTime"));
                     break;
+                case "GROUP":
+                    start= Integer.parseInt(courseJoinMap.get("groupStartTime"));
+                    break;
                 default:
                     break;
             }
@@ -1952,12 +1949,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         LocalDateTime practiceMinute = LocalDateTime.now().plusMinutes(Long.parseLong(sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_PRACTICE_ROOM_MINUTE)));
         LocalDateTime vipMinute = LocalDateTime.now().plusMinutes(Long.parseLong(sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_VIP_ROOM_MINUTE)));
         LocalDateTime pianoMinute = LocalDateTime.now().plusMinutes(Long.parseLong(sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_PIANO_ROOM_MINUTE)));
+        LocalDateTime groupMinute = LocalDateTime.now().plusMinutes(Long.parseLong(sysConfigService.findConfigValue(SysConfigConstant.PRE_CREATE_GROUP_ROOM_MINUTE)));
 
         //课程开始(开课时间 ≤ (NOW + 提前进入房间时间(分)) && NOW ≤ 结束时间)
         List<CourseSchedule> liveStart = baseMapper.selectList(Wrappers.<CourseSchedule>lambdaQuery()
                 .eq(CourseSchedule::getLock, 0)
                 .eq(CourseSchedule::getStatus, CourseScheduleEnum.NOT_START)
-                .eq(CourseSchedule::getType, CourseScheduleEnum.LIVE)
+                .in(CourseSchedule::getType, CourseScheduleEnum.LIVE)
                 .le(CourseSchedule::getStartTime, liveMinute)
                 .ge(CourseSchedule::getEndTime, LocalDateTime.now()));
         List<CourseSchedule> practiceStart = baseMapper.selectList(Wrappers.<CourseSchedule>lambdaQuery()
@@ -1979,6 +1977,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                 .eq(CourseSchedule::getType, CourseScheduleEnum.PIANO_ROOM_CLASS)
                 .le(CourseSchedule::getStartTime, pianoMinute)
                 .ge(CourseSchedule::getEndTime, LocalDateTime.now()));
+
+        List<CourseSchedule> groupStart = baseMapper.selectList(Wrappers.<CourseSchedule>lambdaQuery()
+                .eq(CourseSchedule::getLock, 0)
+                .eq(CourseSchedule::getStatus, CourseScheduleEnum.NOT_START)
+                .eq(CourseSchedule::getType, CourseScheduleEnum.GROUP)
+                .le(CourseSchedule::getStartTime, groupMinute)
+                .ge(CourseSchedule::getEndTime, LocalDateTime.now()));
         if (CollectionUtils.isEmpty(liveStart)) {
             liveStart = new ArrayList<>();
         }
@@ -1991,7 +1996,10 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (CollectionUtils.isEmpty(pianoStart)) {
             pianoStart = new ArrayList<>();
         }
-        List<CourseSchedule> courseStart = Stream.of(liveStart, practiceStart, pianoStart,vipStart).flatMap(Collection::stream).collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(groupStart)) {
+            groupStart = new ArrayList<>();
+        }
+        List<CourseSchedule> courseStart = Stream.of(liveStart, practiceStart, pianoStart,vipStart,groupStart).flatMap(Collection::stream).collect(Collectors.toList());
         if (CollectionUtils.isNotEmpty(courseStart)) {
             //课程状态更新为ING
             baseMapper.updateStartTime(courseStart);
@@ -2001,7 +2009,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         List<CourseScheduleStudentVo> userList = paymentDao.selectUser();
         if (CollectionUtils.isNotEmpty(userList)) {
             List<CourseScheduleStudentVo> practiceList = userList.stream()
-                    .filter(s -> Lists.newArrayList(CourseScheduleEnum.PRACTICE.getCode(),CourseScheduleEnum.VIP.getCode()).contains(s.getType()))
+                    .filter(s -> Lists.newArrayList(CourseScheduleEnum.PRACTICE.getCode()
+                            ,CourseScheduleEnum.VIP.getCode(),CourseScheduleEnum.GROUP.getCode()).contains(s.getType()))
                     .collect(Collectors.toList());
             if (CollectionUtils.isNotEmpty(practiceList)) {//趣纠课/vip课
                 //老师课酬状态改为待结算
@@ -2058,7 +2067,10 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             }
 
             List<CourseScheduleStudentVo> courseList = userList.stream()
-                    .filter(s -> Lists.newArrayList(CourseScheduleEnum.PRACTICE.getCode(),CourseScheduleEnum.VIP.getCode(),CourseScheduleEnum.PIANO_ROOM_CLASS.getCode()).contains(s.getType()))
+                    .filter(s -> Lists.newArrayList(CourseScheduleEnum.PRACTICE.getCode(),
+                            CourseScheduleEnum.VIP.getCode(),
+                            CourseScheduleEnum.GROUP.getCode(),
+                            CourseScheduleEnum.PIANO_ROOM_CLASS.getCode()).contains(s.getType()))
                     .collect(Collectors.toList());
 
             //清除缓存
@@ -2081,9 +2093,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (CollectionUtils.isNotEmpty(completeList)) {
             List<Long> ids = completeList.stream().filter(s -> {
                 return s.getCourseCount().equals(s.getCourseNum());
-            }).map(s -> {
-                return s.getId();
-            }).collect(Collectors.toList());
+            }).map(CourseGroup::getId).collect(Collectors.toList());
             if (CollectionUtils.isNotEmpty(ids)) {
                 //同步课程组状态
                 courseGroupService.getDao().updateBatch(ids);
@@ -2875,6 +2885,11 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         List<CourseScheduleWrapper.MyCourseVo> courseVos = Lists.newArrayList();
         CourseGroup courseGroup = courseGroupService.lambdaQuery().eq(CourseGroup::getId, query.getCourseGroupId()).one();
         Subject subject = subjectService.get(courseGroup.getSubjectId());
+        List<LiveCourseInfoVo.PlanVo> planVos = coursePlanService.queryCoursePlanByGroupId(courseGroup.getId());
+        Map<Long, LiveCourseInfoVo.PlanVo> planMap = new HashMap<>();
+        if(CollectionUtils.isNotEmpty(planVos)){
+            planMap = planVos.stream().collect(Collectors.toMap(LiveCourseInfoVo.PlanVo::getId, Function.identity()));
+        }
         for (CourseSchedule courseSchedule : courseSchedules) {
             CourseScheduleWrapper.MyCourseVo courseVo = new CourseScheduleWrapper.MyCourseVo();
             courseVo.setCourseId(courseSchedule.getId());
@@ -2886,6 +2901,10 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             courseVo.setCourseGroupName(courseGroup.getName() + "-第" + courseSchedule.getClassNum() + "课");
             courseVo.setSubjectId(courseGroup.getSubjectId());
             courseVo.setSubjectName(subject.getName());
+            LiveCourseInfoVo.PlanVo planVo = planMap.get(courseSchedule.getId());
+            if(planVo != null){
+                courseVo.setCoursePlan(planVo.getPlan());
+            }
             if(query.getAttendanceStatus() == null){
                 courseVo.setAttendanceStatus(attendanceList.stream().anyMatch(studentAttendance -> studentAttendance.getCourseScheduleId().equals(courseSchedule.getId())));
             }else {
@@ -3052,6 +3071,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             MessageTypeEnum messageType = MessageTypeEnum.STUDENT_PRACTICE_REMINDER;
             if(courseScheduleEnum == CourseScheduleEnum.VIP){
                 messageType = MessageTypeEnum.STUDENT_VIP_REMINDER;
+            }else if (courseScheduleEnum == CourseScheduleEnum.GROUP){
+                messageType = MessageTypeEnum.STUDENT_GROUP_REMINDER;
             }
             Map<Long, String> sendTeacherMap = new HashMap<>();
             sendTeacherMap.put(courseSchedule.getTeacherId(),teacherMap.get(courseSchedule.getTeacherId()));
@@ -3070,6 +3091,8 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             MessageTypeEnum messageType = MessageTypeEnum.PRACTICE_REMIND;
             if(courseScheduleEnum == CourseScheduleEnum.VIP){
                 messageType = MessageTypeEnum.VIP_REMIND;
+            }else if (courseScheduleEnum == CourseScheduleEnum.GROUP){
+                messageType = MessageTypeEnum.GROUP_REMIND;
             }
             Map<Long, String> sendTeacherMap = new HashMap<>(1);
             sendTeacherMap.put(courseSchedule.getUserId(),studentMap.get(courseSchedule.getUserId()));

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

@@ -47,13 +47,8 @@ public class CourseScheduleStudentPaymentServiceImpl extends ServiceImpl<CourseS
 
     @Override
     public List<CourseScheduleStudentPayment> getByCourseId(Long courseId) {
-        List<CourseScheduleEnum> courseScheduleEnumList = new ArrayList<>();
-        courseScheduleEnumList.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
-        courseScheduleEnumList.add(CourseScheduleEnum.PRACTICE);
-        courseScheduleEnumList.add(CourseScheduleEnum.VIP);
         List<CourseScheduleStudentPayment> list = this.lambdaQuery()
                 .eq(CourseScheduleStudentPayment::getCourseId, courseId)
-                .in(CourseScheduleStudentPayment::getCourseType,courseScheduleEnumList)
                 .isNotNull(CourseScheduleStudentPayment::getUserId)
                 .list();
         if (CollectionUtils.isEmpty(list)) {

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

@@ -408,9 +408,10 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         //imUserFriendService.refreshCustomer(teacherId, ClientEnum.TEACHER, new ArrayList<>(studentIds), ClientEnum.STUDENT);
 
 
-        // 直播课、琴房课校验群成员人数限制
+        // 直播课、琴房课、小组课校验群成员人数限制
         if (CourseScheduleEnum.PIANO_ROOM_CLASS.getCode().equals(courseGroupType)
-            || CourseScheduleEnum.LIVE.getCode().equals(courseGroupType)) {
+            || CourseScheduleEnum.LIVE.getCode().equals(courseGroupType)
+            || CourseScheduleEnum.GROUP.getCode().equals(courseGroupType)) {
 
             // 增加群成员人数限制,若超过限制则不添加到群组
             SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
@@ -438,6 +439,9 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         imGroup.setName(courseGroup.getName());
         imGroup.setType(ImGroupType.COURSE);
         imGroup.setImg(sysConfigService.findConfigValue(SysConfigConstant.ICON_COURSE_GROUP_DEFAULT));
+        if (courseGroup.getType().equals(CourseScheduleEnum.GROUP.name())) {
+            imGroup.setImg(sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_GROUP));
+        }
         imGroup.setCreateTime(now);
         imGroup.setUpdateTime(now);
 //        String imGroupId = UUID.randomUUID() + imGroup.getType().getCode();

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

@@ -570,7 +570,12 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         //课程总金额
         BigDecimal totalExpectPrice = WrapperUtil.sumList(studentPaymentList, CourseScheduleStudentPayment::getActualPrice);
         //查询直播课服务费
-        String liveServiceRateStr = sysConfigService.findConfigValue(SysConfigConstant.LIVE_SERVICE_RATE);
+        String liveServiceRateStr = "20";
+        if (userPaymentOrder.getGoodType() == GoodTypeEnum.LIVE) {
+            liveServiceRateStr = sysConfigService.findConfigValue(SysConfigConstant.LIVE_SERVICE_RATE);
+        } else if (userPaymentOrder.getGoodType() == GoodTypeEnum.GROUP) {
+            liveServiceRateStr = sysConfigService.findConfigValue(SysConfigConstant.GROUP_SERVICE_RATE);
+        }
         BigDecimal liveServiceRate = new BigDecimal(liveServiceRateStr).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
         //总课酬  1 - (1 * 手续费率)
         BigDecimal totalRatePrice = totalExpectPrice.subtract(totalExpectPrice.multiply(liveServiceRate)).setScale(2, RoundingMode.HALF_UP);
@@ -600,7 +605,7 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
             //预计课酬-实际课酬 = 扣除费用
             teacherSalary.setReduceSalary(ex.subtract(ac));
             //备注是为直播课手续费
-            teacherSalary.setReduceSalaryRemark(SysConfigConstant.LIVE_SERVICE_RATE);
+            teacherSalary.setReduceSalaryRemark(userPaymentOrder.getGoodType() == GoodTypeEnum.LIVE? SysConfigConstant.LIVE_SERVICE_RATE:SysConfigConstant.GROUP_SERVICE_RATE);
             if (teacherSalary.getExpectSalary().compareTo(BigDecimal.ZERO) > 0) {
                 teacherSalaryList.add(teacherSalary);
             }
@@ -639,8 +644,12 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
         //课程购买成功后进行消息推送
 
         // 平台学生 发送推送
-        if(checkSendMessage(userPaymentOrder.getUserId(),userPaymentOrder.getOrderClient())) {
-            courseGroupService.buyLiveSendMessage(studentPayment, courseGroup);
+        if(checkSendMessage(userPaymentOrder.getUserId(),userPaymentOrder.getOrderClient()) ) {
+            if (userPaymentOrder.getGoodType() == GoodTypeEnum.LIVE) {
+                courseGroupService.buyLiveSendMessage(studentPayment, courseGroup);
+            } else if (userPaymentOrder.getGoodType() == GoodTypeEnum.GROUP) {
+                courseGroupService.buyGroupSendMessage(studentPayment, courseGroup);
+            }
         }
 
     }

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

@@ -78,8 +78,10 @@ public class StudentTimeServiceImpl extends ServiceImpl<StudentTimeDao, StudentT
                 if (null == studentTime.getFirstVipTime() && GoodTypeEnum.VIP.equals(detailVo.getGoodType())) {
                     studentTime.setFirstVipTime(now);
                 }
-
-                if (null == studentTime.getFirstVipTime() && GoodTypeEnum.SVIP.equals(detailVo.getGoodType())) {
+                if (null == studentTime.getFirstGroupTime() && GoodTypeEnum.GROUP.equals(detailVo.getGoodType())) {
+                    studentTime.setFirstGroupTime(now);
+                }
+                if (null == studentTime.getFirstSvipTime() && GoodTypeEnum.SVIP.equals(detailVo.getGoodType())) {
                     studentTime.setFirstSvipTime(now);
                 }
                 if (null == studentTime.getFirstPracticeTime() && GoodTypeEnum.PRACTICE.equals(detailVo.getGoodType())) {
@@ -168,8 +170,16 @@ public class StudentTimeServiceImpl extends ServiceImpl<StudentTimeDao, StudentT
         if (GoodTypeEnum.VIP.equals(goodType) && null == studentTime.getFirstVipTime()) {
             studentTime.setFirstVipTime(new Date());
         }
-
-        if (GoodTypeEnum.SVIP.equals(goodType) && null == studentTime.getFirstVipTime()) {
+        if (GoodTypeEnum.GROUP.equals(goodType) && null == studentTime.getFirstGroupTime()) {
+            studentTime.setFirstGroupTime(new Date());
+        }
+        if (GoodTypeEnum.DISCOUNT.equals(goodType) && null == studentTime.getFirstDiscountTime()) {
+            studentTime.setFirstDiscountTime(new Date());
+        }
+        if (GoodTypeEnum.VIP_COURSE.equals(goodType) && null == studentTime.getFirstVipCourseTime()) {
+            studentTime.setFirstVipCourseTime(new Date());
+        }
+        if (GoodTypeEnum.SVIP.equals(goodType) && null == studentTime.getFirstSvipTime()) {
             studentTime.setFirstSvipTime(new Date());
         }
         if (GoodTypeEnum.PRACTICE.equals(goodType) && null == studentTime.getFirstPracticeTime()) {

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

@@ -14,33 +14,22 @@ import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.MusicSheetAuthRecordDao;
 import com.yonge.cooleshow.biz.dal.dao.MusicSheetDao;
-import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
-import com.yonge.cooleshow.biz.dal.entity.ImGroup;
-import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
-import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
-import com.yonge.cooleshow.biz.dal.entity.Student;
-import com.yonge.cooleshow.biz.dal.entity.Teacher;
-import com.yonge.cooleshow.biz.dal.entity.UserOrder;
-import com.yonge.cooleshow.biz.dal.entity.UserOrderRefund;
-import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
+import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.service.*;
-import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
 import com.yonge.cooleshow.biz.dal.wrapper.UserInfoWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
 import com.yonge.cooleshow.common.enums.SysUserType;
 import com.yonge.toolset.base.exception.BizException;
-import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.thirdparty.user.realname.RealnameAuthenticationPlugin;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import com.yonge.toolset.utils.idcard.IdcardValidator;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
@@ -66,44 +55,27 @@ public class SysUserServiceImpl implements SysUserService {
     @Resource
     private TeacherService teacherService;
     @Resource
-    private MessageSenderPluginContext messageSenderPluginContext;
-
-    @Autowired
     private UserOrderService userOrderService;
-
-    @Autowired
+    @Resource
     private UserOrderRefundService userOrderRefundService;
-
-    @Autowired
+    @Resource
     private ImGroupMemberService imGroupMemberService;
-
-    @Autowired
+    @Resource
     private ImGroupService imGroupService;
-
-    @Autowired
-    private ImGroupCoreService imGroupCoreService;
-
-    @Autowired
+    @Resource
     private CourseGroupService courseGroupService;
-
-    @Autowired
+    @Resource
     private VideoLessonGroupService videoLessonGroupService;
-
-    @Autowired
+    @Resource
     private UserAccountService userAccountService;
-
-    @Autowired
+    @Resource
     private MallPortalFeignService mallPortalFeignService;
-
-    @Autowired
+    @Resource
     private ImUserFriendService imUserFriendService;
-
-    @Autowired
+    @Resource
     private MusicSheetDao musicSheetDao;
-
-    @Autowired
+    @Resource
     private MusicSheetAuthRecordDao musicSheetAuthRecordDao;
-
     @Resource
     private MessageFeignClientService messageFeignClientService;
     @Override
@@ -278,29 +250,19 @@ public class SysUserServiceImpl implements SysUserService {
             // 趣纠课
             List<CourseGroup> list = courseGroupService.lambdaQuery()
                 .eq(CourseGroup::getTeacherId, userId)
-                .in(CourseGroup::getType, Arrays.asList("PRACTICE", "LIVE", "PIANO_ROOM_CLASS"))
+                .in(CourseGroup::getType, Arrays.asList("PRACTICE", "LIVE", "PIANO_ROOM_CLASS", "GROUP","VIP"))
                 .in(CourseGroup::getStatus, Arrays.asList("ING", "APPLY", "NOT_SALE"))
                 .list();
-            String courseMsg ="";
+            StringBuffer courseMsg = new StringBuffer();
             if (!CollectionUtils.isEmpty(list)) {
-                List<String> courseTypes = list.stream().map(o -> o.getType()).distinct().collect(Collectors.toList());
-                if (courseTypes.contains(CourseScheduleEnum.LIVE.name())) {
-                    courseMsg += "直播课";
-                }
-                if (courseTypes.contains(CourseScheduleEnum.PRACTICE.name())){
-                    if (courseMsg.length() > 0) {
-                        courseMsg+="/";
-                    }
-                    courseMsg += "趣纠课";
-                }
-                if (courseTypes.contains(CourseScheduleEnum.PIANO_ROOM_CLASS.name())){
-                    if (courseMsg.length() > 0) {
-                        courseMsg+="/";
-                    }
-                    courseMsg += "琴房课";
-                }
+                List<String> courseTypes = list.stream().map(CourseGroup::getType).distinct().collect(Collectors.toList());
+                this.appendErrMsg(courseMsg,courseTypes,CourseScheduleEnum.LIVE);
+                this.appendErrMsg(courseMsg,courseTypes,CourseScheduleEnum.PRACTICE);
+                this.appendErrMsg(courseMsg,courseTypes,CourseScheduleEnum.PIANO_ROOM_CLASS);
+                this.appendErrMsg(courseMsg,courseTypes,CourseScheduleEnum.VIP);
+                this.appendErrMsg(courseMsg,courseTypes,CourseScheduleEnum.GROUP);
                 if (courseMsg.length() > 0) {
-                    courseMsg="账号存在未开始/进行中的" + courseMsg;
+                    courseMsg.insert(0,"账号存在未开始/进行中的");
                 }
             }
             // 视频课
@@ -311,9 +273,9 @@ public class SysUserServiceImpl implements SysUserService {
 
             if (videoCourse > 0) {
                 if (courseMsg.length() > 0) {
-                    courseMsg+="和未下架的视频课";
+                    courseMsg.append("和未下架的视频课");
                 } else {
-                    courseMsg="账号存在未下架的视频课";
+                    courseMsg.append("账号存在未下架的视频课");
                 }
             } else {
                 // 判断审核中的视频课
@@ -324,15 +286,15 @@ public class SysUserServiceImpl implements SysUserService {
                     .count();
                 if (videoCourse > 0) {
                     if (courseMsg.length() > 0) {
-                        courseMsg+="和未下架的视频课";
+                        courseMsg.append("和未下架的视频课");
                     } else {
-                        courseMsg="账号存在未下架的视频课";
+                        courseMsg.append("账号存在未下架的视频课");
                     }
                 }
 
             }
             if (courseMsg.length() > 0) {
-                errMsg.add(courseMsg);
+                errMsg.add(courseMsg.toString());
             }
 
             // 存在未提现的金额
@@ -379,6 +341,15 @@ public class SysUserServiceImpl implements SysUserService {
         return logOffs;
     }
 
+    private void appendErrMsg(StringBuffer courseMsg,List<String> courseTypes,CourseScheduleEnum courseScheduleEnum) {
+        if (courseTypes.contains(courseScheduleEnum.name())) {
+            if (courseMsg.length() > 0) {
+                courseMsg.append("/");
+            }
+            courseMsg.append(courseScheduleEnum.getMsg());
+        }
+    }
+
     private Map<String, String> hasUnfinishedOrder(Long userId) {
         // 商城订单 0->待付款;1->待发货;2->已发货
         HttpResponseResult<Map<String, Set<CheckStatus>>> httpResponseResult = mallPortalFeignService.checkOrderStatus(userId);

+ 12 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserAccountServiceImpl.java

@@ -300,6 +300,7 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
         BigDecimal practiceAmount = BigDecimal.ZERO;
         BigDecimal vipCourseAmount = BigDecimal.ZERO;
         BigDecimal liveAmount = BigDecimal.ZERO;
+        BigDecimal groupAmount = BigDecimal.ZERO;
         BigDecimal videoAmount = BigDecimal.ZERO;
         BigDecimal musicAmount = BigDecimal.ZERO;
 
@@ -317,6 +318,7 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
             practiceAmount = practiceAmount.add(info.getPracticeAmount());
             vipCourseAmount = vipCourseAmount.add(info.getVipCourseAmount());
             liveAmount = liveAmount.add(info.getLiveAmount());
+            groupAmount = groupAmount.add(info.getGroupAmount());
             videoAmount = videoAmount.add(info.getVideoAmount());
             musicAmount = musicAmount.add(info.getMusicAmount());
 
@@ -331,7 +333,7 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
         AccountTotal total = new AccountTotal();
 
         total.setTotalInAmount(
-                practiceAmount.add(liveAmount).add(videoAmount).add(musicAmount)
+                practiceAmount.add(liveAmount).add(groupAmount).add(videoAmount).add(musicAmount)
                         .add(liveShareAmount).add(videoShareAmount).add(musicShareAmount)
                         .add(vipShareAmount).add(mallShareAmount).add(actiRegistShareAmount).add(albumShareAmount)
                         .add(vipCourseAmount)
@@ -352,6 +354,12 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
                     .divide(total.getTotalInAmount(), 4, RoundingMode.HALF_UP)
                     .multiply(new BigDecimal("100")));
 
+
+            total.setGroupAmount(groupAmount);
+            total.setGroupRate(total.getGroupAmount()
+                    .divide(total.getTotalInAmount(), 4, RoundingMode.HALF_UP)
+                    .multiply(new BigDecimal("100")));
+
             total.setVideoAmount(videoAmount);
             total.setVideoRate(total.getVideoAmount()
                     .divide(total.getTotalInAmount(), 4, RoundingMode.HALF_UP)
@@ -398,6 +406,7 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
                             .subtract(total.getPracticeRate())
                             .subtract(total.getVipCourseRate())
                             .subtract(total.getLiveRate())
+                            .subtract(total.getGroupRate())
                             .subtract(total.getVideoRate())
                             .subtract(total.getMusicRate())
                             .subtract(total.getMusicShareRate())
@@ -550,6 +559,8 @@ public class UserAccountServiceImpl extends ServiceImpl<UserAccountDao, UserAcco
                 null == info.getVipCourseAmount() ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : info.getVipCourseAmount().setScale(2, RoundingMode.HALF_UP));
         info.setLiveAmount(
                 null == info.getLiveAmount() ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : info.getLiveAmount().setScale(2, RoundingMode.HALF_UP));
+        info.setGroupAmount(
+                null == info.getLiveAmount() ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : info.getGroupAmount().setScale(2, RoundingMode.HALF_UP));
         info.setVideoAmount(
                 null == info.getVideoAmount() ? BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP) : info.getVideoAmount().setScale(2, RoundingMode.HALF_UP));
         info.setMusicAmount(

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

@@ -11,6 +11,9 @@ import com.yonge.cooleshow.biz.dal.dto.search.UserOrderRefundPaymentSearch;
 import com.yonge.cooleshow.biz.dal.dao.UserOrderRefundBillDao;
 import com.yonge.cooleshow.biz.dal.service.UserOrderRefundBillService;
 
+import java.util.Collections;
+import java.util.List;
+
 
 @Service
 public class UserOrderRefundBillServiceImpl extends ServiceImpl<UserOrderRefundBillDao, UserOrderRefundBill> implements UserOrderRefundBillService {
@@ -32,4 +35,10 @@ public class UserOrderRefundBillServiceImpl extends ServiceImpl<UserOrderRefundB
         return baseMapper.getByTransNoOrOrderNo(transNo, refundOrderNo);
     }
 
+    @Override
+    public List<UserOrderRefundBill> getPendingList() {
+        return baseMapper.getPendingList();
+
+    }
+
 }

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

@@ -34,6 +34,7 @@ import com.yonge.toolset.payment.base.model.RefundBill;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
 import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
 import com.yonge.toolset.payment.core.service.PaymentClient;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -664,6 +665,11 @@ public class UserOrderRefundServiceImpl extends ServiceImpl<UserOrderRefundDao,
         }
     }
 
+    @Override
+    public List<UserOrderRefund> getByOrderNo(String orderNo, @NotNull List<Long> orderDetailIds) {
+        return baseMapper.getByOrderNo(orderNo, orderDetailIds);
+    }
+
     /**
      * 处理退款后账户
      *

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

@@ -219,6 +219,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         orderCancel.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourseFailed);
         //直播课购买
         orderCancel.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseCancel);
+        orderCancel.put(GoodTypeEnum.GROUP, courseGroupService::buyLiveCourseCancel);
         // 曲目购买
         orderCancel.put(GoodTypeEnum.MUSIC, musicSheetService::buyMusicSheetCancel);
         // 专辑购买
@@ -1186,6 +1187,8 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_DISCOUNT);
         } else if (GoodTypeEnum.VIP_COURSE.equals(goodTypeEnum)) {
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_VIP_COURSE);
+        } else if (GoodTypeEnum.GROUP.equals(goodTypeEnum)) {
+            configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_GROUP);
         }
         return configValue;
     }
@@ -1500,6 +1503,8 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.ACTI_REGIST_ACCOUNT_PERIOD)));
         } else if (GoodTypeEnum.VIP_COURSE.equals(goodType)) {
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.VIP_COURSE_ACCOUNT_PERIOD)));
+        }else if (GoodTypeEnum.GROUP.equals(goodType)) {
+            instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.GROUP_COURSE_ACCOUNT_PERIOD)));
         }
         return instance.getTime();
     }

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

@@ -47,6 +47,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.PostConstruct;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.MessageFormat;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Consumer;
@@ -179,6 +180,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         orderGoodsCreate.put(GoodTypeEnum.DISCOUNT, memberPriceSettingsService::discountCreate);
         //直播课程购买
         orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
+        orderGoodsCreate.put(GoodTypeEnum.GROUP, courseGroupService::buyLiveCourse);
         //趣纠课购买
         orderGoodsCreate.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourse);
         //视频课购买
@@ -207,6 +209,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
 
         //直播课程购买
         orderSuccessAfter.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseAfter);
+        orderSuccessAfter.put(GoodTypeEnum.GROUP, courseGroupService::buyLiveCourseAfter);
         //趣纠课购买
         orderSuccessAfter.put(GoodTypeEnum.PRACTICE, scheduleService::buyPracticeCourseAfter);
         orderSuccessAfter.put(GoodTypeEnum.VIP_COURSE, scheduleService::buyPracticeCourseAfter);
@@ -222,6 +225,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         paymentSuccess.put(GoodTypeEnum.PRACTICE, paymentDivMemberRecordService::practiceCourse);
         paymentSuccess.put(GoodTypeEnum.VIP_COURSE, paymentDivMemberRecordService::practiceCourse);
         paymentSuccess.put(GoodTypeEnum.LIVE, paymentDivMemberRecordService::liveCourse);
+        paymentSuccess.put(GoodTypeEnum.GROUP, paymentDivMemberRecordService::liveCourse);
         paymentSuccess.put(GoodTypeEnum.VIDEO, paymentDivMemberRecordService::videoCourse);
         paymentSuccess.put(GoodTypeEnum.ALBUM, paymentDivMemberRecordService::musicSheet);
         paymentSuccess.put(GoodTypeEnum.VIP, paymentDivMemberRecordService::vip);
@@ -827,6 +831,11 @@ DISCOUNT("畅学卡")
                         actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
                     }
                     break;
+                case GROUP:
+                    if (goodsInfo.getGoodType().equals(GoodTypeEnum.GROUP)) {
+                        actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
+                    }
+                    break;
                 case VIDEO:
                     if (goodsInfo.getGoodType().equals(GoodTypeEnum.VIDEO)) {
                         actualPrice = goodsInfo.getUserOrderDetail().getActualPrice();
@@ -1689,6 +1698,16 @@ DISCOUNT("畅学卡")
         if (orderDetailIds != null) {
             collect = detail.getOrderDetailList().stream().filter(o -> orderDetailIds.contains(o.getId())).collect(Collectors.toList());
         }
+        if (CollectionUtils.isEmpty(collect)) {
+            throw new BizException("订单明细不存在");
+        }
+
+        // 判断当前商品是否已退款
+        List<UserOrderRefund> userOrderRefunds = userOrderRefundService.getByOrderNo(orderNo,collect.stream().map(o -> o.getId()).collect(Collectors.toList()));
+        if (CollectionUtils.isNotEmpty(userOrderRefunds)) {
+            throw new BizException("订单商品已退款");
+        }
+
 
         BigDecimal reduce = collect.stream().map(o -> o.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
         // 提交退款申请记录
@@ -1723,7 +1742,6 @@ DISCOUNT("畅学卡")
         DistributedLock.of(redissonClient).runIfLockCanGet(lockNameInner, () -> {
             if (StringUtils.isEmpty(paymentOrder.getTransNo()) || reduce.compareTo(BigDecimal.ZERO) == 0) {
                 orderRefundBill.setStatus(TradeStatusEnum.succeeded);
-                userOrderRefundBillService.save(orderRefundBill);
             } else {
                 try {
                     RefundResp refundResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor()).refund(refundOrder);
@@ -1854,9 +1872,9 @@ DISCOUNT("畅学卡")
             // 已产生三方交易流水号,先判断三方订单支付状态若在支付中,则重复返回相同支付配置参数;避免用户重复支付
             // 原生支付(微信,支付宝)流水号后产品,需要查询三方支付订单状态
             if (StringUtils.isNotBlank(paymentOrder.getTransNo())
-                || EPaymentVendor.ORIGINAL.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())
-                || EPaymentVendor.WXPAY.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())
-                || EPaymentVendor.ALIPAY.name().equalsIgnoreCase(paymentOrder.getPaymentVendor())) {
+                || paymentOrder.getPaymentVendor().startsWith(EPayerType.ORIGINAL.name().toLowerCase())
+                || paymentOrder.getPaymentVendor().startsWith(EPaymentVendor.WXPAY.name().toLowerCase())
+                || paymentOrder.getPaymentVendor().startsWith(EPaymentVendor.ALIPAY.name().toLowerCase())) {
 
                 // 获取三方支付订单信息,根据订单状处理
                 PaymentResp paymentResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
@@ -1893,4 +1911,49 @@ DISCOUNT("畅学卡")
         },10L,TimeUnit.SECONDS);
 
     }
+
+    @Override
+    public void scanRefundOrderRecord() {
+        List<UserOrderRefundBill> pendingList = userOrderRefundBillService.getPendingList();
+        for (UserOrderRefundBill userOrderRefundBill : pendingList) {
+            UserOrderRefund refund = userOrderRefundService.getById(userOrderRefundBill.getRefundId());
+            if (Objects.isNull(refund)) {
+                continue;
+            }
+            UserPaymentOrderWrapper.UserPaymentOrder paymentOrder = userPaymentOrderService.getUserPaymentOrderByOrderNo(refund.getOrderNo());
+            if (Objects.isNull(paymentOrder)) {
+                continue;
+            }
+            // 查询退款状态
+            // 查询订单退款状态
+
+            try {
+                RefundResp refundResp = paymentServiceContext.getPaymentService(paymentOrder.getPaymentVendor())
+                        .queryRefund(userOrderRefundBill.getTransNo(), userOrderRefundBill.getBillNo(), paymentOrder.getOrderNo());
+
+                log.info("refundConfirm REFUND refundResp={}, paymentStatus={},", JSON.toJSONString(refundResp), paymentOrder.getStatus());
+                // 退款申请处理中
+                if (PaymentStatus.PENDDING == refundResp.getPaymentStatus()) {
+                    continue;
+                }
+                // 申请请求失败
+                if (PaymentStatus.FAILED == refundResp.getPaymentStatus()) {
+                    userOrderRefundBill.setStatus(TradeStatusEnum.failed);
+                    userOrderRefundBill.setPayFailMsg(refundResp.getMsg());
+                    userOrderRefundBill.setTransNo(refundResp.getTransNo());
+                } else  if (PaymentStatus.SUCCESSED == refundResp.getPaymentStatus()) {
+                    // 更新退款订单状态
+                    userOrderRefundBill.setStatus(TradeStatusEnum.succeeded);
+                    userOrderRefundBill.setPayFailMsg("");
+                    userOrderRefundBill.setTransNo(refundResp.getTransNo());
+                }
+            } catch (Exception e) {
+                userOrderRefundBill.setStatus(TradeStatusEnum.failed);
+                userOrderRefundBill.setPayFailMsg(e.getMessage());
+                log.error("refundOnly orderNo={}", userOrderRefundBill.getBillNo(), e);
+            }
+            userOrderRefundBillService.updateById(userOrderRefundBill);
+        }
+
+    }
 }

+ 12 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupVo.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.vo;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -24,6 +25,10 @@ public class CourseGroupVo implements Serializable {
     @ApiModelProperty(value = "名称")
     private String courseGroupName;
 
+
+    @ApiModelProperty(value = "类型 practice趣纠课 live直播课")
+    private String type;
+
     @ApiModelProperty(value = "声部名称")
     private String subjectName;
 
@@ -58,6 +63,9 @@ public class CourseGroupVo implements Serializable {
     @ApiModelProperty(value = "课程数")
     private Integer courseNum;
 
+    @ApiModelProperty(value = "已上完课的课程数")
+    private Integer completeCourseNum;
+
     @ApiModelProperty(value = "课程介绍")
     private String courseIntroduce;
 
@@ -72,13 +80,16 @@ public class CourseGroupVo implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     private Date salesEndDate;
 
+    @ApiModelProperty(value = "最大成课人数")
+    private Integer maxStudentNum;
+
     @ApiModelProperty(value = "最少成课人数")
     private Integer mixStudentNum;
 
     @ApiModelProperty(value = "直播课成课后生成的im群id")
     private String imGroupId;
 
-    @ApiModelProperty(value = "当前学生有没有购买该课程组   0没有购买    1已经购买过 ")
+    @ApiModelProperty(value = "当前学生有没有购买该课程组   0没有购买,1已经购买过,2不可购买")
     private Integer existBuy;
 
     @ApiModelProperty("下架原因")

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseInfoVo.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.biz.dal.vo;
+
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+@ApiModel(value = "CourseInfoVo", description = "课程组详情")
+public class CourseInfoVo extends CourseGroupVo implements Serializable {
+
+    @ApiModelProperty(value = "true 自己的课,false 其他老师的课程")
+    private Boolean myself;
+
+    @ApiModelProperty(value = "是否审核时可见 (0:否  1:是)")
+    private YesOrNoEnum auditVersion = YesOrNoEnum.NO;
+
+    @ApiModelProperty("学位认证 0:未认证 1:已认证 ")
+    private YesOrNoEnum degreeFlag;
+
+    @ApiModelProperty("教师资格认证 0:未认证 1:已认证 ")
+    private YesOrNoEnum teacherFlag;
+}

+ 5 - 71
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseRepliedVo.java

@@ -3,12 +3,15 @@ package com.yonge.cooleshow.biz.dal.vo;
 import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
 import java.util.Date;
 
 /**
  * @Author: cy
  * @Date: 2022/4/19
  */
+@Data
 @ApiModel(value = "CourseRepliedVo")
 public class CourseRepliedVo extends CourseScheduleReplied {
     @ApiModelProperty("用户名")
@@ -37,75 +40,6 @@ public class CourseRepliedVo extends CourseScheduleReplied {
     @ApiModelProperty("声部名称")
     private String subjectName;
 
-    public String getRealName() {
-        return realName;
-    }
-
-    public void setRealName(String realName) {
-        this.realName = realName;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    public String getAvatar() {
-        return avatar;
-    }
-
-    public void setAvatar(String avatar) {
-        this.avatar = avatar;
-    }
-
-    public String getClassDate() {
-        return classDate;
-    }
-
-    public void setClassDate(String classDate) {
-        this.classDate = classDate;
-    }
-
-    public String getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(String startTime) {
-        this.startTime = startTime;
-    }
-
-    public String getEndTime() {
-        return endTime;
-    }
-
-    public void setEndTime(String endTime) {
-        this.endTime = endTime;
-    }
-
-    public String getStatus() {
-        return status;
-    }
-
-    public void setStatus(String status) {
-        this.status = status;
-    }
-
-    public Integer getSubjectId() {
-        return subjectId;
-    }
-
-    public void setSubjectId(Integer subjectId) {
-        this.subjectId = subjectId;
-    }
-
-    public String getSubjectName() {
-        return subjectName;
-    }
-
-    public void setSubjectName(String subjectName) {
-        this.subjectName = subjectName;
-    }
+    @ApiModelProperty("课程组名称")
+    private String courseGroupName;
 }

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseStudent.java

@@ -84,5 +84,11 @@ public class CourseStudent implements Serializable {
 
     @ApiModelProperty(value = "课程介绍")
     private String courseIntroduce;
+
+    @ApiModelProperty(value = "学员数量")
+    private Integer studentCount;
+
+    @ApiModelProperty(value = "最大成课人数")
+    private Integer maxStudentNum;
 }
 

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseGroupVo.java

@@ -59,6 +59,9 @@ public class LiveCourseGroupVo {
     @ApiModelProperty(value = "手机号")
     private String phone;
 
+    @ApiModelProperty(value = "老师姓名")
+    private String teacherName;
+
     @ApiModelProperty("订单号")
     private String orderNo;
 

+ 0 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/LiveCourseInfoVo.java

@@ -33,7 +33,6 @@ public class LiveCourseInfoVo extends CourseGroupVo implements Serializable {
     @ApiModelProperty("学位认证 0:未认证 1:已认证 ")
     private YesOrNoEnum degreeFlag;
 
-
     @ApiModelProperty("教师资格认证 0:未认证 1:已认证 ")
     private YesOrNoEnum teacherFlag;
 

+ 4 - 119
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MyRepliedVo.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.vo;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.io.Serializable;
 import java.util.Date;
@@ -11,6 +12,7 @@ import java.util.Date;
  * @Date: 2022/4/13
  */
 @ApiModel(value = "MyRepliedVo")
+@Data
 public class MyRepliedVo implements Serializable {
     @ApiModelProperty(value = "课程id")
     private Long courseId;
@@ -56,123 +58,6 @@ public class MyRepliedVo implements Serializable {
     @ApiModelProperty(value = "学生评价内容")
     private String studentRepliedStr;
 
-    public String getStudentRepliedStr() {
-        return studentRepliedStr;
-    }
-
-    public void setStudentRepliedStr(String studentRepliedStr) {
-        this.studentRepliedStr = studentRepliedStr;
-    }
-
-    public Integer getStudentReplied() {
-        return studentReplied;
-    }
-
-    public void setStudentReplied(Integer studentReplied) {
-        this.studentReplied = studentReplied;
-    }
-
-    public Integer getTeacherReplied() {
-        return teacherReplied;
-    }
-
-    public void setTeacherReplied(Integer teacherReplied) {
-        this.teacherReplied = teacherReplied;
-    }
-
-    public String getRealName() {
-        return realName;
-    }
-
-    public void setRealName(String realName) {
-        this.realName = realName;
-    }
-
-    public Long getCourseId() {
-        return courseId;
-    }
-
-    public void setCourseId(Long courseId) {
-        this.courseId = courseId;
-    }
-
-    public Long getCourseGroupId() {
-        return courseGroupId;
-    }
-
-    public void setCourseGroupId(Long courseGroupId) {
-        this.courseGroupId = courseGroupId;
-    }
-
-    public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    public String getAvatar() {
-        return avatar;
-    }
-
-    public void setAvatar(String avatar) {
-        this.avatar = avatar;
-    }
-
-    public Date getClassDate() {
-        return classDate;
-    }
-
-    public void setClassDate(Date classDate) {
-        this.classDate = classDate;
-    }
-
-    public Date getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(Date startTime) {
-        this.startTime = startTime;
-    }
-
-    public Date getEndTime() {
-        return endTime;
-    }
-
-    public void setEndTime(Date endTime) {
-        this.endTime = endTime;
-    }
-
-    public Integer getSubjectId() {
-        return subjectId;
-    }
-
-    public void setSubjectId(Integer subjectId) {
-        this.subjectId = subjectId;
-    }
-
-    public String getSubjectName() {
-        return subjectName;
-    }
-
-    public void setSubjectName(String subjectName) {
-        this.subjectName = subjectName;
-    }
-
-    public String getScore() {
-        return score;
-    }
-
-    public void setScore(String score) {
-        this.score = score;
-    }
+    @ApiModelProperty("课程组名称")
+    private String courseGroupName;
 }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/TeacherLiveCourseInfoVo.java

@@ -49,6 +49,9 @@ public class TeacherLiveCourseInfoVo implements Serializable {
     @ApiModelProperty(value = "课程人数")
     private Integer studentCount;
 
+    @ApiModelProperty(value = "最大成课人数")
+    private Integer maxStudentCount;
+
     @ApiModelProperty(value = "课程图片")
     private String backgroundPic;
 

+ 6 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/res/AccountTotal.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.vo.res;
 
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 import java.math.BigDecimal;
 import java.util.List;
@@ -10,6 +11,7 @@ import java.util.List;
  * @Author: liweifan
  * @Data: 2022/4/21 11:29
  */
+@Data
 @ApiModel(value = "AccountTotal", description = "用户账户统计对象")
 public class AccountTotal {
     @ApiModelProperty("总收入")
@@ -26,6 +28,10 @@ public class AccountTotal {
     private BigDecimal liveAmount = BigDecimal.ZERO;
     @ApiModelProperty("直播课-百分比")
     private BigDecimal liveRate = BigDecimal.ZERO;
+    @ApiModelProperty("小组课")
+    private BigDecimal groupAmount = BigDecimal.ZERO;
+    @ApiModelProperty("小组课-百分比")
+    private BigDecimal groupRate = BigDecimal.ZERO;
     @ApiModelProperty("视频课")
     private BigDecimal videoAmount = BigDecimal.ZERO;
     @ApiModelProperty("视频课-百分比")

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/course/CourseScheduleWrapper.java

@@ -70,6 +70,9 @@ public class CourseScheduleWrapper {
         @ApiModelProperty(value = "声部名称")
         private String subjectName;
 
+        @ApiModelProperty(value = "课程规划")
+        private String coursePlan;
+
         @ApiModelProperty(value = "学员列表")
         private List<CourseStudentVo> courseStudentVos;
     }

+ 56 - 34
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml

@@ -17,6 +17,7 @@
         <result column="sales_end_date_" jdbcType="TIMESTAMP" property="salesEndDate"/>
         <result column="background_pic_" jdbcType="VARCHAR" property="backgroundPic"/>
         <result column="mix_student_num_" jdbcType="INTEGER" property="mixStudentNum"/>
+        <result column="max_student_num_" jdbcType="INTEGER" property="maxStudentNum"/>
         <result column="course_start_time_" jdbcType="TIMESTAMP" property="courseStartTime"/>
         <result column="created_by_" jdbcType="INTEGER" property="createdBy"/>
         <result column="created_time_" jdbcType="TIMESTAMP" property="createdTime"/>
@@ -32,7 +33,7 @@
         id_
         , type_, teacher_id_, name_, subject_id_, single_course_minutes_, course_num_,
         complete_course_num_, course_introduce_, course_price_, status_, sales_start_date_,
-        sales_end_date_, background_pic_, mix_student_num_,pre_student_num_, im_group_id_,
+        sales_end_date_, background_pic_, mix_student_num_,max_student_num_,pre_student_num_, im_group_id_,
         course_start_time_, created_by_, created_time_, updated_by_, updated_time_,reason_,course_plan_
     </sql>
 
@@ -40,12 +41,12 @@
             parameterType="com.yonge.cooleshow.biz.dal.entity.CourseGroup">
         insert into course_group(type_, teacher_id_, name_, subject_id_, single_course_minutes_, course_num_,
         complete_course_num_, course_introduce_, course_price_, status_, sales_start_date_, sales_end_date_, background_pic_,
-        mix_student_num_,pre_student_num_,im_group_id_, course_start_time_, created_by_, created_time_, updated_by_, updated_time_,reason_,course_plan_)
+        mix_student_num_,max_student_num_,pre_student_num_,im_group_id_, course_start_time_, created_by_, created_time_, updated_by_, updated_time_,reason_,course_plan_)
         values
         <foreach collection="entities" item="entity" separator=",">
             (#{entity.type}, #{entity.teacherId}, #{entity.name}, #{entity.subjectId}, #{entity.singleCourseMinutes},
             #{entity.courseNum}, #{entity.completeCourseNum}, #{entity.courseIntroduce}, #{entity.coursePrice}, #{entity.status},
-            #{entity.salesStartDate}, #{entity.salesEndDate}, #{entity.backgroundPic}, #{entity.mixStudentNum},
+            #{entity.salesStartDate}, #{entity.salesEndDate}, #{entity.backgroundPic}, #{entity.mixStudentNum},#{entity.maxStudentNum},
             #{entity.preStudentNum},#{entity.imGroupId},#{entity.courseStartTime}, #{entity.createdBy}, #{entity.createdTime}, #{entity.updatedBy},
             #{entity.updatedTime},#{entity.reason},#{entity.coursePlan})
         </foreach>
@@ -69,6 +70,7 @@
         b.sales_start_date_           as salesStartDate,
         b.sales_end_date_             as salesEndDate,
         b.mix_student_num_            as mixStudentNum,
+        b.max_student_num_            as maxStudentNum,
         b.im_group_id_              as imGroupId,
         b.reason_ as                   reason,
         b.course_plan_ as coursePlan,
@@ -118,6 +120,7 @@
                         b.sales_start_date_           as salesStartDate,
                         b.sales_end_date_             as salesEndDate,
                         b.mix_student_num_            as mixStudentNum,
+                        b.max_student_num_            as maxStudentNum,
                         b.im_group_id_                as imGroupId,
                         b.reason_ as                   reason,
                         b.course_plan_ as coursePlan,
@@ -155,13 +158,15 @@
             <if test="param.subjectId != null ">
                 and #{param.subjectId} = b.subject_id_
             </if>
+            <if test="param.type != null and param.type != ''">
+                and b.type_ = #{param.type}
+            </if>
         </where>
     </select>
 
     <select id="selectAdminLivePage" resultType="com.yonge.cooleshow.biz.dal.vo.LiveCourseGroupVo">
         select distinct
         cg.id_ as courseGroupId,
-
         cg.reason_ as                   reason,
         cg.name_ as name,
         cg.complete_course_num_ as endCourseNum,
@@ -176,28 +181,35 @@
             cssp.order_no_ as orderNo,
         </if>
         cg.im_group_id_  as imGroupId,
-        cg.course_plan_ as coursePlan
+        cg.course_plan_ as coursePlan,
+        su.username_ as teacherName,
+        su.phone_ as phone
         from course_group cg
-        left join course_schedule_student_payment cssp on cg.id_ = cssp.course_group_id_
-        left join sys_user su on su.id_ = cssp.user_id_
+        left join sys_user su on su.id_ = cg. teacher_id_
+        <if test="param.studentId != null">
+            left join course_schedule_student_payment cssp on cg.id_ = cssp.course_group_id_
+        </if>
         <where>
             <if test="param.teacherId != null">
                 and #{param.teacherId} = cg.teacher_id_
+                <if test="param.search != null and param.search !=''">
+                    and  (cg.id_ = #{param.search} or cg.name_ like concat('%',#{param.search},'%'))
+                </if>
             </if>
             <if test="param.studentId != null">
                 and #{param.studentId} = cssp.user_id_
-            </if>
-            <if test="param.search != null and param.search !=''">
-                and  (
-                    cg.id_ like concat('%',#{param.search},'%')
+                <if test="param.search != null and param.search !=''">
+                    and  (
+                    cg.id_ = #{param.search}
                     or cg.name_ like concat('%',#{param.search},'%')
-                    or su.id_ like concat('%',#{param.search},'%')
+                    or su.id_ = #{param.search}
                     or su.username_ like concat('%',#{param.search},'%')
                     or su.phone_  like concat('%',#{param.search},'%')
-                )
-            </if>
-            <if test="param.orderNo != null and param.orderNo != ''">
-                and cssp.order_no_ like concat('%',#{param.orderNo},'%')
+                    )
+                </if>
+                <if test="param.orderNo != null and param.orderNo != ''">
+                    and cssp.order_no_ like concat('%',#{param.orderNo},'%')
+                </if>
             </if>
             <if test="param.subjectId != null">
                 and #{param.subjectId} = cg.subject_id_
@@ -247,7 +259,7 @@
         left join user_order as o on a.order_no_ = o.order_no_
         left join sys_user as su on o.user_id_ = su.id_
         <where>
-            a.good_type_ = 'LIVE' and o.status_ = 'PAID'
+            o.status_ = 'PAID'
             <if test="param.courseGroupId != null">
                 and #{param.courseGroupId} = a.biz_id_
             </if>
@@ -497,23 +509,27 @@
         FROM course_group cg
         LEFT JOIN `subject` sb ON cg.subject_id_=sb.id_
         LEFT JOIN sys_user su ON su.id_=cg.teacher_id_
-        LEFT JOIN (SELECT course_group_id_,COUNT(1) AS count_ FROM course_schedule WHERE type_='LIVE' AND status_='COMPLETE' GROUP BY course_group_id_) cm ON cg.id_=cm.course_group_id_
-        LEFT JOIN (SELECT course_group_id_,start_time_ FROM course_schedule WHERE type_='LIVE' GROUP BY course_group_id_) st ON cg.id_=st.course_group_id_
-        WHERE cg.type_='LIVE'
-        <if test="param.search != null and param.search != ''">
-            AND (
-            cg.id_ LIKE concat('%',#{param.search},'%') OR
-            cg.teacher_id_ LIKE concat('%',#{param.search},'%') OR
-            cg.name_ LIKE concat('%',#{param.search},'%') OR
-            su.username_ LIKE concat('%',#{param.search},'%')
-            )
-        </if>
-        <if test="param.subjectId != null">
-            AND cg.subject_id_ = #{param.subjectId}
-        </if>
-        <if test="param.status != null and param.status != ''">
-            AND cg.status_ = #{param.status}
-        </if>
+        LEFT JOIN (SELECT course_group_id_,COUNT(1) AS count_ FROM course_schedule WHERE type_ = #{param.groupType} AND status_='COMPLETE' GROUP BY course_group_id_) cm ON cg.id_=cm.course_group_id_
+        LEFT JOIN (SELECT course_group_id_,start_time_ FROM course_schedule WHERE type_ = #{param.groupType} GROUP BY course_group_id_) st ON cg.id_=st.course_group_id_
+        <where>
+            <if test="param.search != null and param.search != ''">
+                AND (
+                cg.id_ LIKE concat('%',#{param.search},'%') OR
+                cg.teacher_id_ LIKE concat('%',#{param.search},'%') OR
+                cg.name_ LIKE concat('%',#{param.search},'%') OR
+                su.username_ LIKE concat('%',#{param.search},'%')
+                )
+            </if>
+            <if test="param.subjectId != null">
+                AND cg.subject_id_ = #{param.subjectId}
+            </if>
+            <if test="param.groupType != null and param.groupType != ''">
+                AND cg.type_ = #{param.groupType}
+            </if>
+            <if test="param.status != null and param.status != ''">
+                AND cg.status_ = #{param.status}
+            </if>
+        </where>
     </select>
     <select id="selectLiveGroupStudent" resultType="com.yonge.cooleshow.biz.dal.vo.CourseSchedulePaymentVo">
         SELECT
@@ -1106,4 +1122,10 @@
         </where>
         GROUP BY cg.id_
     </select>
+
+    <update id="updateLockNum">
+        update course_group
+        set lock_num_ = lock_num_ + #{num}
+        where id_ = #{groupId} and lock_num_ + #{num} &lt;= max_student_num_ and lock_num_ + #{num} &gt;= 0
+    </update>
 </mapper>

+ 11 - 3
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseHomeworkMapper.xml

@@ -106,6 +106,14 @@
         left join course_homework ch on ch.course_schedule_id_ = cs.id_
         left join course_schedule_student_payment cssp on cssp.course_id_ = cs.id_
         left join student_course_homework sch  on sch.course_schedule_id_ = cssp.course_id_ and sch.student_id_ = cssp.user_id_
+        <if test="param.search != null and param.search != ''">
+            <if test="param.clientType == 'TEACHER'">
+                left join sys_user su on su.id_ = cs.teacher_id_
+            </if>
+            <if test="param.clientType == 'STUDENT'">
+                left join sys_user su on su.id_ = cssp.user_id_
+            </if>
+        </if>
         left join (select cssp.course_id_,
                 count(cssp.id_) as studentNum,
                 sum(if(sch.attachments_ is null or sch.attachments_ = '',0,1)) as commitNum,
@@ -128,6 +136,9 @@
                     and ch.id_ is not null
                 </if>
             </if>
+            <if test="param.search != null and param.search != ''">
+                and su.username_ like concat('%',#{param.search},'%')
+            </if>
             <if test="param.submit != null">
                 <if test="param.submit.code == 0">
                     and sch.id_ is null
@@ -136,9 +147,6 @@
                     and sch.id_ is not null
                 </if>
             </if>
-            <if test="param.search != null and param.search != ''">
-                and cs.name_ like concat('%',#{param.search},'%')
-            </if>
             <if test="param.courseStatus != null">
                 and cs.status_ = #{param.courseStatus}
             </if>

+ 21 - 14
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseScheduleMapper.xml

@@ -60,7 +60,7 @@
                 sum(if(a.end_time_ &lt;= now(),1,0)) as expTime,
                 sum(if(a.end_time_ &gt; now(),1,0)) as unExpTime
             from course_schedule a
-            where a.lock_ = 0 and a.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE')
+            where a.lock_ = 0 and a.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE','GROUP')
             <if test="userId != null and userId != ''">
                 and a.teacher_id_ = #{userId}
             </if>
@@ -73,7 +73,7 @@
                 avg (b.score_) as starGrade
             from course_schedule a
             join course_schedule_replied b on a.id_ = b.course_schedule_id_
-            where a.lock_ = 0 and a.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE') and b.score_ is not null
+            where a.lock_ = 0 and a.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE','GROUP') and b.score_ is not null
             <if test="userId != null and userId != ''">
                 and a.teacher_id_ = #{userId}
             </if>
@@ -93,7 +93,7 @@
         from student t
         left join course_schedule_student_payment a on t.user_id_ = a.user_id_
         left join course_schedule b on a.course_id_ = b.id_
-        where b.lock_ = 0 and b.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE')
+        where b.lock_ = 0 and b.type_ in ('PRACTICE','PIANO_ROOM_CLASS','VIP','LIVE','GROUP')
             <if test="userId != null and userId != ''">
                 and t.user_id_ = #{userId}
             </if>
@@ -165,9 +165,10 @@
         su.avatar_ as avatar,
         cs.course_num_ as courseNum,
         cs.complete_course_num_ as completeCourseNum,
-        cs.course_introduce_ as courseIntroduce
+        cs.course_introduce_ as courseIntroduce,
+        cs.max_student_num_ as maxStudentNum
         from (select * from (
-        select cg.course_num_,cg.complete_course_num_,cg.course_introduce_,cg.pre_student_num_,
+        select cg.course_num_,cg.complete_course_num_,cg.course_introduce_,cg.pre_student_num_,cg.max_student_num_,
         cg.background_pic_,cg.im_group_id_,cg.name_,cg.subject_id_,cg.teacher_id_,
         CASE WHEN cg.status_ = 'COMPLETE' THEN cg.status_ WHEN cs.status_ = 'NOT_START' THEN 'NOT_START' ELSE 'ING' END as `status_`,
         cs.type_,cs.course_group_id_,cs.class_date_,cs.start_time_,cs.end_time_,cs.id_,cs.class_num_
@@ -206,7 +207,7 @@
             cs.status_ AS `status`,
             g.subject_id_ AS subjectId,
             sb.name_ AS subjectName,
-            g.name_ AS courseGroupName,
+            concat(cg.name_,'-第',cs.class_num_,'课') as courseGroupName,
             u.del_flag_ as delFlag,
             p.course_id_ AS courseId,
             p.course_group_id_ AS courseGoupId,
@@ -306,7 +307,7 @@
         FROM course_group g
         LEFT JOIN course_schedule s ON g.id_=s.course_group_id_
         WHERE g.teacher_id_=#{teacherId}
-        AND g.type_='LIVE'
+        AND g.type_ in ('LIVE','GROUP')
         AND g.status_ IN ('COMPLETE','ING')
         <![CDATA[ AND s.class_date_  >= #{startDate} ]]>
         <![CDATA[ AND s.class_date_  <= #{endDate} ]]>
@@ -382,7 +383,7 @@
         WHERE cs.lock_=0
         AND cs.status_ IN ('ING','COMPLETE','NOT_START')
         AND g.status_ IN ('ING', 'COMPLETE')
-        AND cs.type_ IN ('LIVE','PIANO_ROOM_CLASS')
+        AND cs.type_ IN ('LIVE','PIANO_ROOM_CLASS','GROUP')
         AND cs.teacher_id_=#{param.teacherId}
         AND cs.class_date_=#{param.classDate}
         AND cs.id_ IN(
@@ -392,7 +393,7 @@
             AND p.course_group_id_ = c.course_group_id_
             AND c.teacher_id_=#{param.teacherId}
             AND c.class_date_=#{param.classDate}
-            AND c.type_ IN ('LIVE','PIANO_ROOM_CLASS')
+            AND c.type_ IN ('LIVE','PIANO_ROOM_CLASS','GROUP')
             )
         UNION
         SELECT
@@ -552,7 +553,7 @@
         AND s.status_ IN ('ING','NOT_START','COMPLETE')
         AND g.status_ IN ('ING', 'COMPLETE','APPLY','OUT_SALE')
         AND s.id_ IN
-        (SELECT course_id_ FROM course_schedule_student_payment WHERE user_id_ = #{param.studentId} AND course_type_ IN ('LIVE','PIANO_ROOM_CLASS'))
+        (SELECT course_id_ FROM course_schedule_student_payment WHERE user_id_ = #{param.studentId} AND course_type_ IN ('LIVE','PIANO_ROOM_CLASS','GROUP'))
         AND s.class_date_ = #{param.classDate}
         ORDER BY startTime
     </select>
@@ -577,7 +578,9 @@
         g.im_group_id_  as imGroupId,
         g.course_introduce_ as courseIntroduce,
         g.course_num_ as courseNum,
-        g.complete_course_num_ as completeCourseNum
+        g.complete_course_num_ as completeCourseNum,
+        IFNULL(g.pre_student_num_, 0) as studentCount,
+        g.max_student_num_ as maxStudentNum
         FROM
         (select * from (
         select cssp.user_id_,cssp.course_id_,cssp.order_no_,cs.type_,
@@ -598,6 +601,9 @@
             <if test="param.subjectId != null">
                 AND g.subject_id_ = #{param.subjectId}
             </if>
+            <if test="param.groupState !=null and param.groupState !=''">
+                AND find_in_set(cg.status_, #{param.groupState})
+            </if>
             <if test="param.courseState != null">
                 <if test="param.courseState == 'COMPLETE'">
                     AND g.status_ = 'COMPLETE'
@@ -675,7 +681,8 @@
         FROM video_lesson_group g
         LEFT JOIN sys_user u ON g.teacher_id_=u.id_
         LEFT JOIN `subject` s ON g.lesson_subject_=s.id_
-        LEFT JOIN (SELECT video_lesson_group_id_ ,COUNT(1) AS count_ FROM video_lesson_purchase_record WHERE order_status_='PAID' GROUP BY video_lesson_group_id_) r ON g.id_= r.video_lesson_group_id_
+        LEFT JOIN (SELECT video_lesson_group_id_ ,COUNT(1) AS count_ FROM video_lesson_purchase_record
+                                                                     WHERE order_status_='PAID' GROUP BY video_lesson_group_id_) r ON g.id_= r.video_lesson_group_id_
         WHERE u.del_flag_ = 0 and g.audit_status_='PASS' and g.shelves_flag_ = 1 and #{appAuditVersion} = g.audit_version_
         <if test="subjectId != null">
         	and g.lesson_subject_ = #{subjectId}
@@ -749,7 +756,7 @@
         LEFT JOIN sys_user u ON s.teacher_id_=u.id_
         LEFT JOIN course_group g ON s.course_group_id_=g.id_
         WHERE s.teacher_id_=#{teacherId}
-        AND s.type_ IN ('LIVE','PIANO_ROOM_CLASS')
+        AND s.type_ IN ('LIVE','PIANO_ROOM_CLASS','GROUP')
         AND s.status_ IN ('ING','NOT_START')  and g.status_='ING'
         and date_format(s.class_date_,'%Y-%m-%d') = date_format(now(),'%Y-%m-%d')
         ORDER BY ABS(NOW() - s.start_time_) ASC
@@ -998,7 +1005,7 @@
         FROM course_schedule_teacher_salary ts
         LEFT JOIN course_group g ON ts.course_group_id_ = g.id_
         LEFT JOIN course_schedule_student_payment sp ON ts.course_schedule_id_ = sp.course_id_
-        WHERE ts.course_group_type_ in ('PRACTICE','VIP')
+        WHERE ts.course_group_type_ in ('PRACTICE','VIP','GROUP')
         AND ts.status_ = 'WAIT'
         <![CDATA[ AND DATE_FORMAT(ts.update_time_,'%Y-%m-%d') <= #{day}]]>
     </select>

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

@@ -125,6 +125,7 @@
             r.course_group_id_ AS courseGroupId,
             r.score_ AS score,
             r.student_replied_ AS studentRepliedStr,
+            concat(g.name_,'-第',s.class_num_,'课') as courseGroupName,
             g.subject_id_ AS subjectId,
             sb.name_ AS subjectName,
             s.class_date_ AS classDate,
@@ -166,7 +167,7 @@
             s.start_time_ AS startTime,
             s.end_time_ AS endTime,
             s.status_ AS status,
-
+            concat(g.name_,'-第',s.class_num_,'课') as courseGroupName,
             g.subject_id_ AS subjectId,
             sb.name_ AS subjectName
         FROM course_schedule_replied t

+ 11 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentMapper.xml

@@ -260,6 +260,17 @@
                             GROUP BY a.subject_id_
                         )
                     </if>
+                    <if test="type == null or type =='GROUP'">
+                        union all
+                        (
+                            select
+                                a.subject_id_ as subject_id_
+                            from course_group a
+                            join course_schedule_student_payment a1 on a.id_ = a1.course_group_id_
+                            where a.type_ = 'GROUP' and a1.user_id_ = #{userId}
+                            GROUP BY a.subject_id_
+                        )
+                    </if>
                     <if test="type == null or type =='VIP'">
                         union all
                         (

+ 6 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/StudentTimeMapper.xml

@@ -12,12 +12,16 @@
         <result column="first_mall_time_" property="firstMallTime" />
         <result column="first_activity_time_" property="firstActivityTime" />
         <result column="first_pay_time_" property="firstPayTime" />
+        <result column="first_group_time_" property="firstGroupTime" />
+        <result column="first_vip_course_time_" property="firstVipCourseTime" />
+        <result column="first_discount_time_" property="firstDiscountTime" />
     </resultMap>
 
     <!-- 表字段 -->
     <sql id="baseColumns">
          t.user_id_ as userId
         , t.first_vip_time_ as firstVipTime
+        , t.first_vip_course_time_ as firstVipCourseTime
         , t.first_svip_time_ as firstSvipTime
         , t.first_practice_time_ as firstPracticeTime
         , t.first_video_time_ as firstVideoTime
@@ -26,5 +30,7 @@
         , t.first_mall_time_ as firstMallTime
         , t.first_activity_time_ as firstActivityTime
         , t.first_pay_time_ as firstPayTime
+        , t.first_group_time_ as firstGroupTime
+        , t.first_discount_time_ as firstDiscountTime
         </sql>
 </mapper>

+ 5 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/TeacherMapper.xml

@@ -343,6 +343,11 @@
                 (select subject_id_ as subject_id_ from course_group where type_ = 'VIP' and teacher_id_ =
                 #{userId} GROUP BY subject_id_)
             </if>
+            <if test="type == null or type =='GROUP'">
+                union all
+                (select subject_id_ as subject_id_ from course_group where type_ = 'GROUP' and teacher_id_ =
+                #{userId} GROUP BY subject_id_)
+            </if>
             <if test="type == null or type =='LIVE'">
                 union all
                 (select subject_id_ as subject_id_ from course_group where type_ = 'LIVE' and teacher_id_ = #{userId}

+ 3 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserAccountMapper.xml

@@ -84,7 +84,7 @@
                 and a.post_status_ = 'RECORDED' and a.in_or_out_ = 'IN') as amountRecorded,
             (select sum(a.trans_amount_) from user_cash_account_record a where a.account_id_ = t.user_id_
                 and a.post_status_ in ('RECORDED','WAIT') and a.in_or_out_ = 'IN'
-                and a.biz_type_ in ('LIVE_SHARE','VIDEO_SHARE','MUSIC_SHARE','ALBUM_SHARE','VIP_SHARE','MALL_SHARE','ACTI_REGIST_SHARE')) as amountShare
+                and a.biz_type_ in ('LIVE_SHARE','GROUP_SHARE','VIDEO_SHARE','MUSIC_SHARE','ALBUM_SHARE','VIP_SHARE','MALL_SHARE','ACTI_REGIST_SHARE')) as amountShare
         FROM user_cash_account t
         where t.user_id_ = #{id}
     </select>
@@ -106,6 +106,7 @@
             sum(a.practiceAmount) as practiceAmount,
             sum(a.vipCourseAmount) as vipCourseAmount,
             sum(a.liveAmount) as liveAmount,
+            sum(a.groupAmount) as groupAmount,
             sum(a.videoAmount) as videoAmount,
             sum(a.musicAmount) as musicAmount,
             sum(a.liveShareAmount) as liveShareAmount,
@@ -122,6 +123,7 @@
                 sum(if(t.biz_type_ = 'PRACTICE',t.trans_amount_,0)) as practiceAmount,
                 sum(if(t.biz_type_ = 'VIP_COURSE',t.trans_amount_,0)) as vipCourseAmount,
                 sum(if(t.biz_type_ = 'LIVE',t.trans_amount_,0)) as liveAmount,
+                sum(if(t.biz_type_ = 'GROUP',t.trans_amount_,0)) as groupAmount,
                 sum(if(t.biz_type_ = 'VIDEO',t.trans_amount_,0)) as videoAmount,
                 sum(if(t.biz_type_ = 'MUSIC',t.trans_amount_,0)) as musicAmount,
                 sum(if(t.biz_type_ = 'LIVE_SHARE',t.trans_amount_,0)) as liveShareAmount,

+ 3 - 3
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserAccountRecordMapper.xml

@@ -239,7 +239,7 @@
                 max(t.update_time_) as create_time_,
                 max(t.update_time_) as update_time_
             from user_cash_account_record t
-            where t.biz_type_ = 'LIVE'
+            where t.biz_type_ in ('LIVE','GROUP')
             <include refid="selectCondition"/>
             group by t.account_id_,t.in_or_out_,t.post_status_,t.biz_type_,biz_id_,biz_name_
             union all
@@ -256,10 +256,10 @@
                 t.update_time_ as create_time_,
                 t.update_time_ as update_time_
             from user_cash_account_record t
-            where t.biz_type_ != 'LIVE'
+            where t.biz_type_ not in ('LIVE','GROUP')
             <include refid="selectCondition"/>
         ) t
-        left join course_schedule a on t.biz_id_ = a.id_ and t.biz_type_ in ('PRACTICE','LIVE','VIP_COURSE')
+        left join course_schedule a on t.biz_id_ = a.id_ and t.biz_type_ in ('PRACTICE','LIVE','GROUP','VIP_COURSE')
         order by t.update_time_ desc,t.id_ desc
     </select>
 

+ 10 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderMapper.xml

@@ -183,6 +183,12 @@
                     <if test="param.goodType !=null and param.goodType !=''">
                         and d.good_type_ = #{param.goodType}
                     </if>
+                <if test="param.goodTypes != null and param.goodTypes.size() != 0">
+                    and d.good_type_ in
+                    <foreach collection="param.goodTypes" item="item" separator="," open="(" close=")">
+                        #{item}
+                    </foreach>
+                </if>
                     <if test="param.bizId !=null">
                         and d.biz_id_ = #{param.bizId}
                     </if>
@@ -267,6 +273,10 @@
             select 1 from user_order_detail od where t.order_no_ = od.order_no_
             and (
                 (st.first_vip_time_ is null and od.good_type_ = 'VIP') or
+                (st.first_svip_time_ is null and od.good_type_ = 'SVIP') or
+                (st.first_vip_course_time_ is null and od.good_type_ = 'VIP_COURSE') or
+                (st.first_group_time_ is null and od.good_type_ = 'GROUP') or
+                (st.first_discount_time_ is null and od.good_type_ = 'DISCOUNT') or
                 (st.first_practice_time_ is null and od.good_type_ = 'PRACTICE') or
                 (st.first_video_time_ is null and od.good_type_ = 'VIDEO') or
                 (st.first_live_time_ is null and od.good_type_ = 'LIVE') or

+ 6 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderRefundBillMapper.xml

@@ -55,4 +55,10 @@
             </if>
         </where>
     </select>
+
+    <select id="getPendingList" resultMap="BaseResultMap">
+        select t.*
+        from user_order_refund_bill t
+        where t.status_ = 'pending'
+    </select>
 </mapper>

+ 8 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserOrderRefundMapper.xml

@@ -77,4 +77,12 @@
                   and FIND_IN_SET(d.id_,r.oredr_detil_ids_)
           )
     </select>
+
+    <select id="getByOrderNo" resultMap="BaseResultMap">
+        SELECT <include refid="baseColumns" /> FROM user_order_refund t
+        WHERE t.order_no_ = #{orderNo} and
+        <foreach collection="orderDetailIds" item="item" open="(" separator="," close=")">
+            FIND_IN_SET(#{item}, t.oredr_detil_ids_)
+        </foreach>
+    </select>
 </mapper>

+ 1 - 1
pom.xml

@@ -24,7 +24,7 @@
 		<redisson.version>3.11.5</redisson.version>
 		<maven.test.skip>true</maven.test.skip>
 		<cbs.version>1.0.27</cbs.version>
-		<microsvc.version>1.1.4</microsvc.version>
+		<microsvc.version>1.1.9</microsvc.version>
 	</properties>