liujc 10 months ago
parent
commit
105415e6fb
100 changed files with 2926 additions and 708 deletions
  1. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java
  2. 6 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MemberPriceSettingsController.java
  3. 13 12
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java
  4. 28 15
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java
  5. 56 6
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java
  6. 12 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TeacherBindingUserVo.java
  7. 3 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/teacher/TeacherVO.java
  8. 2 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupController.java
  9. 2 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImUserFriendController.java
  10. 38 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MemberPriceSettingsController.java
  11. 40 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java
  12. 9 4
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java
  13. 3 3
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupController.java
  14. 4 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImUserFriendController.java
  15. 17 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MemberPriceSettingsController.java
  16. 22 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java
  17. 25 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/StudentController.java
  18. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherController.java
  19. 2 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java
  20. 33 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserOrderController.java
  21. 1 1
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java
  22. 3 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/WebCourseScheduleController.java
  23. 2 2
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/config/CustomerServiceConfig.java
  24. 3 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java
  25. 5 13
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java
  26. 17 0
      cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml
  27. 16 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  28. 1 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/RewardTypeEnum.java
  29. 1 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/UnitEnum.java
  30. 1 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/payment/EPaymentType.java
  31. 13 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java
  32. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ImUserFriendDao.java
  33. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetDao.java
  34. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java
  35. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java
  36. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/VipCardRecordDao.java
  37. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/BasicUserInfo.java
  38. 44 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/OrderReq.java
  39. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/TeacherSubmitReq.java
  40. 7 13
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MemberPriceSettingsSearch.java
  41. 22 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetRelatedQueryInfo.java
  42. 23 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetSearch.java
  43. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/OrderSearch.java
  44. 13 9
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/StudentSearch.java
  45. 9 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherSearch.java
  46. 23 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VipRecordSearch.java
  47. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java
  48. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImGroup.java
  49. 12 58
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MemberPriceSettings.java
  50. 16 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentTime.java
  51. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/Teacher.java
  52. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserOrderDetail.java
  53. 27 130
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/VipCardRecord.java
  54. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/AccountBizTypeEnum.java
  55. 33 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EUserVipType.java
  56. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EVipRecordStatus.java
  57. 46 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EVipType.java
  58. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/GoodTypeEnum.java
  59. 24 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java
  60. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/OrderTypeEnum.java
  61. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/PeriodEnum.java
  62. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/SourceTypeEnum.java
  63. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponCategoryEnum.java
  64. 21 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java
  65. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupMemberService.java
  66. 9 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImGroupService.java
  67. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/ImUserFriendService.java
  68. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MemberPriceSettingsService.java
  69. 4 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  70. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java
  71. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TeacherService.java
  72. 41 5
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VipCardRecordService.java
  73. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/ImGroupCoreService.java
  74. 12 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/impl/ImGroupCoreServiceImpl.java
  75. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityRewardServiceImpl.java
  76. 8 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  77. 32 17
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  78. 9 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CustomerServiceBatchSendingServiceImpl.java
  79. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/HomeServiceImpl.java
  80. 113 44
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberAuditServiceImpl.java
  81. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupMemberServiceImpl.java
  82. 112 34
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImGroupServiceImpl.java
  83. 133 39
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java
  84. 244 57
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MemberPriceSettingsServiceImpl.java
  85. 48 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  86. 12 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PaymentDivMemberRecordServiceImpl.java
  87. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/PlatformCashAccountRecordServiceImpl.java
  88. 60 17
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  89. 8 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentTimeServiceImpl.java
  90. 310 30
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java
  91. 11 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantApplyRecordServiceImpl.java
  92. 21 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TenantGroupServiceImpl.java
  93. 5 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserAccountRecordServiceImpl.java
  94. 19 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserBindingTeacherServiceImpl.java
  95. 11 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicServiceImpl.java
  96. 37 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  97. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserPaymentCoreServiceImpl.java
  98. 43 43
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserTenantAlbumRecordServiceImpl.java
  99. 750 67
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VipCardRecordServiceImpl.java
  100. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetDetailVo.java

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/ImGroupController.java

@@ -65,7 +65,7 @@ public class ImGroupController extends BaseController {
     @PostMapping(value = "/getDetail/{groupId}")
     @PostMapping(value = "/getDetail/{groupId}")
     @PreAuthorize("@pcs.hasPermissions('imGroup/detail')")
     @PreAuthorize("@pcs.hasPermissions('imGroup/detail')")
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
-        ImGroup group = imGroupService.getById(groupId);
+        ImGroup group = imGroupService.getGroupById(groupId);
         if (group == null) {
         if (group == null) {
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
         }
         }

+ 6 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/MemberPriceSettingsController.java

@@ -1,5 +1,7 @@
 package com.yonge.cooleshow.admin.controller;
 package com.yonge.cooleshow.admin.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -69,6 +71,9 @@ public class MemberPriceSettingsController extends BaseController {
 		}
 		}
 		memberPriceSettings.setUpdateBy(user.getId());
 		memberPriceSettings.setUpdateBy(user.getId());
 		memberPriceSettings.setUpdateTime(new Date());
 		memberPriceSettings.setUpdateTime(new Date());
-		return status(memberPriceSettingsService.updateById(memberPriceSettings));
+		boolean update = memberPriceSettingsService.update(memberPriceSettings, new UpdateWrapper<MemberPriceSettings>().lambda()
+				.set(MemberPriceSettings::getDesc, memberPriceSettings.getDesc())
+				.eq(MemberPriceSettings::getId, memberPriceSettings.getId()));
+		return status(update);
 	}
 	}
 }
 }

+ 13 - 12
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/StudentController.java

@@ -251,9 +251,9 @@ public class StudentController extends BaseController {
         OutputStream outputStream = response.getOutputStream();
         OutputStream outputStream = response.getOutputStream();
         try {
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"学生编号", "学生姓名", "真实姓名", "性别", "出生日期",
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"学生编号", "学生姓名", "真实姓名", "性别", "出生日期",
-                    "年龄", "专业", "手机号码", "是否是会员", "注册时间", "用户状态", "学生来源","小组"}, new String[]{
+                    "年龄", "专业", "手机号码", "会员类型", "会员结束时间", "注册时间", "用户状态", "学生来源","小组"}, new String[]{
                     "userId", "username", "realName", "gender.msg", "birthdate", "age", "subjectName", "phone",
                     "userId", "username", "realName", "gender.msg", "birthdate", "age", "subjectName", "phone",
-                    "isVip.msg", "createTime", "userStatus.msg", "tenantName", "tenantGroupName"}, rows);
+                    "vipType.name", "membershipEndTimeStr", "createTime", "userStatus.msg", "tenantName", "tenantGroupName"}, rows);
             response.setContentType("application/octet-stream");
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attac:wq" +
             response.setHeader("Content-Disposition", "attac:wq" +
                     "hment;filename=学生列表-" + DateUtil.getDate(new Date()) + ".xls");
                     "hment;filename=学生列表-" + DateUtil.getDate(new Date()) + ".xls");
@@ -274,16 +274,16 @@ public class StudentController extends BaseController {
         }
         }
     }
     }
 
 
-    @PostMapping("/addVip")
-    @ApiOperation(value = "添加会员")
-    @PreAuthorize("@pcs.hasPermissions('student/addVip')")
-    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if (sysUser == null || sysUser.getId() == null) {
-            return failed("用户信息获取失败");
-        }
-        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.STUDENT, sysUser));
-    }
+//    @PostMapping("/addVip")
+//    @ApiOperation(value = "添加会员")
+//    @PreAuthorize("@pcs.hasPermissions('student/addVip')")
+//    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null || sysUser.getId() == null) {
+//            return failed("用户信息获取失败");
+//        }
+//        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.STUDENT, sysUser));
+//    }
 
 
 
 
     @PostMapping("/vipRecord")
     @PostMapping("/vipRecord")
@@ -291,6 +291,7 @@ public class StudentController extends BaseController {
     @PreAuthorize("@pcs.hasPermissions('student/vipRecord')")
     @PreAuthorize("@pcs.hasPermissions('student/vipRecord')")
     public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
     public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
 
 
+        recordSearch.setDisplayFlag(true);
         recordSearch.setClient(ClientEnum.STUDENT);
         recordSearch.setClient(ClientEnum.STUDENT);
         return succeed(vipCardRecordService.vipRecord(recordSearch));
         return succeed(vipCardRecordService.vipRecord(recordSearch));
     }
     }

+ 28 - 15
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/TeacherController.java

@@ -218,9 +218,9 @@ public class TeacherController extends BaseController {
         OutputStream outputStream = response.getOutputStream();
         OutputStream outputStream = response.getOutputStream();
         try {
         try {
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"老师编号", "昵称", "姓名", "手机号", "老师类型",
             HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"老师编号", "昵称", "姓名", "手机号", "老师类型",
-                    "注册时间", "认证时间", "状态", "是否是会员", "徽章", "机构", "小组"}, new String[]{
+                    "注册时间", "认证时间", "状态", "会员类型", "会员结束时间", "徽章", "机构", "小组"}, new String[]{
                     "userId", "username", "realName", "phone", "entryFlag.code == 1 ? '达人' : '游客'", "createTime",
                     "userId", "username", "realName", "phone", "entryFlag.code == 1 ? '达人' : '游客'", "createTime",
-                    "entryAuthDate","userStatus.msg", "isVip.code == 1 ? '是' : '否'", "tag", "tenantName",
+                    "entryAuthDate","userStatus.msg", "vipType.name", "membershipEndTimeStr", "tag", "tenantName",
                     "tenantGroupName"}, rows);
                     "tenantGroupName"}, rows);
             response.setContentType("application/octet-stream");
             response.setContentType("application/octet-stream");
             response.setHeader("Content-Disposition", "attac:wq" +
             response.setHeader("Content-Disposition", "attac:wq" +
@@ -242,25 +242,25 @@ public class TeacherController extends BaseController {
         }
         }
     }
     }
 
 
-    @PostMapping("/addVip")
-    @ApiOperation(value = "添加会员")
-    @PreAuthorize("@pcs.hasPermissions('teacher/addVip')")
-    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
-
-
-        SysUser sysUser = sysUserFeignService.queryUserInfo();
-        if (sysUser == null  || sysUser.getId() == null) {
-            return failed("用户信息获取失败");
-        }
-        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.TEACHER,sysUser));
-    }
+//    @PostMapping("/addVip")
+//    @ApiOperation(value = "添加会员")
+//    @PreAuthorize("@pcs.hasPermissions('teacher/addVip')")
+//    public HttpResponseResult<Boolean> addVip(@Valid @RequestBody VipSubmitReq vipSubmitReq) {
+//
+//
+//        SysUser sysUser = sysUserFeignService.queryUserInfo();
+//        if (sysUser == null  || sysUser.getId() == null) {
+//            return failed("用户信息获取失败");
+//        }
+//        return succeed(memberPriceSettingsService.addVip(vipSubmitReq, ClientEnum.TEACHER,sysUser));
+//    }
 
 
 
 
     @PostMapping("/vipRecord")
     @PostMapping("/vipRecord")
     @ApiOperation(value = "会员记录")
     @ApiOperation(value = "会员记录")
     @PreAuthorize("@pcs.hasPermissions('teacher/vipRecord')")
     @PreAuthorize("@pcs.hasPermissions('teacher/vipRecord')")
     public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
     public HttpResponseResult<PageInfo<VipRecordVo>> vipRecord(@Valid @RequestBody VipRecordSearch recordSearch) {
-
+        recordSearch.setDisplayFlag(true);
         recordSearch.setClient(ClientEnum.TEACHER);
         recordSearch.setClient(ClientEnum.TEACHER);
         return succeed(vipCardRecordService.vipRecord(recordSearch));
         return succeed(vipCardRecordService.vipRecord(recordSearch));
     }
     }
@@ -355,4 +355,17 @@ public class TeacherController extends BaseController {
         imGroupService.setTeacherFansGroup();
         imGroupService.setTeacherFansGroup();
         return succeed();
         return succeed();
     }
     }
+
+    /**
+     * 老师账号冻结/解冻
+     */
+    @PostMapping("/updateLock/{teacherId}")
+    @ApiOperation(value = "老师账号冻结/解冻")
+    @PreAuthorize("@pcs.hasPermissions('teacher/updateLock')")
+    public HttpResponseResult updateLock(@PathVariable("teacherId") Long teacherId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        teacherService.updateLock(sysUser, teacherId);
+        return succeed();
+    }
+
 }
 }

+ 56 - 6
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/controller/VipCardRecordController.java

@@ -1,16 +1,30 @@
 package com.yonge.cooleshow.admin.controller;
 package com.yonge.cooleshow.admin.controller;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dao.UserOrderDao;
+import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
+import com.yonge.cooleshow.biz.dal.enums.EVipRecordStatus;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
 import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
+import org.checkerframework.checker.units.qual.A;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -18,6 +32,9 @@ import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
 
 
+import javax.annotation.Resource;
+import java.util.stream.Collectors;
+
 @RestController
 @RestController
 @RequestMapping("${app-config.url.admin:}/vipCardRecord")
 @RequestMapping("${app-config.url.admin:}/vipCardRecord")
 @Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
 @Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
@@ -26,22 +43,55 @@ public class VipCardRecordController extends BaseController {
     @Autowired
     @Autowired
     private VipCardRecordService vipCardRecordService;
     private VipCardRecordService vipCardRecordService;
 
 
-	/**
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private UserOrderDao userOrderDao;
+
+    /**
      * 查询单条
      * 查询单条
      */
      */
     @GetMapping("/detail/{orderDetilId}")
     @GetMapping("/detail/{orderDetilId}")
     @ApiOperation(value = "详情", notes = "传入订单详情id")
     @ApiOperation(value = "详情", notes = "传入订单详情id")
     public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("orderDetilId") Long orderDetilId) {
     public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("orderDetilId") Long orderDetilId) {
-    	return succeed(vipCardRecordService.detail(orderDetilId));
-	}
-    
+        return succeed(vipCardRecordService.detail(orderDetilId));
+    }
+
     /**
     /**
      * 查询分页
      * 查询分页
      */
      */
     @PostMapping("/page")
     @PostMapping("/page")
     @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
     @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
     public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
     public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
-		IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
+        IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
         return succeed(PageUtil.pageInfo(pages));
         return succeed(PageUtil.pageInfo(pages));
-	}
+    }
+
+
+    @ApiOperation("添加/扣减会员")
+    @PostMapping("/add")
+    @PreAuthorize("@pcs.hasPermissions('vipCardRecord/add')")
+    public HttpResponseResult<Void> add(@RequestBody @Validated VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        addVipCardRecord.setCreateBy(sysUser.getId());
+        if (addVipCardRecord.getStatus().equals(EVipRecordStatus.ADD)) {
+            addVipCardRecord.setSourceType(SourceTypeEnum.PLATFORM);
+        } else if (addVipCardRecord.getStatus().equals(EVipRecordStatus.DEDUCTION)) {
+            addVipCardRecord.setSourceType(SourceTypeEnum.PLATFORM_DEDUCT);
+        }
+
+        // 判断是否有待支付订单 如果有返回不可下单
+        OrderSearch search = new OrderSearch();
+        search.setOrderClient(addVipCardRecord.getClientType().name());
+        search.setGoodType(Lists.newArrayList(GoodTypeEnum.VIP, GoodTypeEnum.SVIP).stream().map(GoodTypeEnum::name).collect(Collectors.joining(",")));
+        search.setUserId(addVipCardRecord.getUserId());
+
+        UserOrderVo userOrderVo = userOrderDao.getPendingOrder(search);
+        if (null != userOrderVo) {
+            throw new BizException(997, "当前用户存在未支付订单,不可操作添加/扣减会员");
+        }
+        vipCardRecordService.add(addVipCardRecord);
+        return succeed();
+    }
 }
 }

+ 12 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/TeacherBindingUserVo.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.admin.io.request;
 package com.yonge.cooleshow.admin.io.request;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
@@ -100,6 +101,9 @@ public class TeacherBindingUserVo {
         @ApiModelProperty(value = "是否会员 0否 1是")
         @ApiModelProperty(value = "是否会员 0否 1是")
         private YesOrNoEnum isVip;
         private YesOrNoEnum isVip;
 
 
+        @ApiModelProperty("用户会员类型")
+        private EUserVipType vipType;
+
 
 
         @ApiModelProperty("课程数")
         @ApiModelProperty("课程数")
         private Long courseNum;
         private Long courseNum;
@@ -204,6 +208,14 @@ public class TeacherBindingUserVo {
         public void setBindingTime(Date bindingTime) {
         public void setBindingTime(Date bindingTime) {
             this.bindingTime = bindingTime;
             this.bindingTime = bindingTime;
         }
         }
+
+        public EUserVipType getVipType() {
+            return vipType;
+        }
+
+        public void setVipType(EUserVipType vipType) {
+            this.vipType = vipType;
+        }
     }
     }
 
 
     @ApiModel("BindingStudentCourseQuery-绑定学生课程列表查询")
     @ApiModel("BindingStudentCourseQuery-绑定学生课程列表查询")

+ 3 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/admin/io/request/teacher/TeacherVO.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.admin.io.request.teacher;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -138,5 +139,7 @@ public class TeacherVO {
 
 
         @ApiModelProperty("出生日期")
         @ApiModelProperty("出生日期")
         private Integer age;
         private Integer age;
+
+        private EUserVipType vipType;
     }
     }
 }
 }

+ 2 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupController.java

@@ -136,7 +136,7 @@ public class ImGroupController extends BaseController {
             return failed("无效的用户ID");
             return failed("无效的用户ID");
         }
         }
 
 
-        ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
+        ImUserFriendVO.ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
         if (Objects.isNull(userFriend)) {
         if (Objects.isNull(userFriend)) {
             return failed("当前好友不存在");
             return failed("当前好友不存在");
         }
         }
@@ -145,7 +145,7 @@ public class ImGroupController extends BaseController {
             userFriend.setFriendType(ClientEnum.STUDENT);
             userFriend.setFriendType(ClientEnum.STUDENT);
         }
         }
 
 
-        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+        return succeed(userFriend);
     }
     }
 }
 }
 
 

+ 2 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImUserFriendController.java

@@ -91,7 +91,7 @@ public class ImUserFriendController extends BaseController {
             return failed("无效的用户ID");
             return failed("无效的用户ID");
         }
         }
 
 
-        ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.STUDENT);
+        ImUserFriendVO.ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.STUDENT);
         if (Objects.isNull(userFriend)) {
         if (Objects.isNull(userFriend)) {
             return failed("当前好友不存在");
             return failed("当前好友不存在");
         }
         }
@@ -100,7 +100,7 @@ public class ImUserFriendController extends BaseController {
             userFriend.setFriendType(ClientEnum.TEACHER);
             userFriend.setFriendType(ClientEnum.TEACHER);
         }
         }
 
 
-        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+        return succeed(userFriend);
     }
     }
 }
 }
 
 

+ 38 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MemberPriceSettingsController.java

@@ -6,11 +6,13 @@ import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
 import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
+import com.yonge.cooleshow.biz.dal.wrapper.MemberPriceSettingsWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
@@ -43,10 +45,46 @@ public class MemberPriceSettingsController extends BaseController {
 	@PostMapping("/list")
 	@PostMapping("/list")
 	@ApiOperation(value = "查询列表")
 	@ApiOperation(value = "查询列表")
 	public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
 	public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
+		query.setStatus(true);
 		MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
 		MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
 		return succeed(memberPriceVo);
 		return succeed(memberPriceVo);
 	}
 	}
 
 
+
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/check/{id}")
+    @ApiOperation(value = "检查会员是否有效", notes = "传入id")
+    public HttpResponseResult<Boolean> check(@PathVariable("id") Long id) {
+        MemberPriceSettingsVo detail = memberPriceSettingsService.detail(id);
+        if (detail == null) {
+            return succeed(false);
+        }else if (Boolean.FALSE.equals(detail.getStatus())) {
+            return succeed(false);
+        }
+        return succeed(true);
+    }
+
+
+    /**
+     * 查询单条
+     */
+    @PostMapping("/checkChange")
+    @ApiOperation(value = "检查会员是否有效", notes = "传入id")
+    public HttpResponseResult<Boolean> checkChange(@RequestBody @Validated MemberPriceSettingsWrapper.MemberChange memberChange) {
+        MemberPriceSettingsVo detail = memberPriceSettingsService.detail(memberChange.getId());
+        if (detail == null) {
+            return succeed(false);
+        }else if (Boolean.FALSE.equals(detail.getStatus())) {
+            return succeed(false);
+        } else if (memberChange.getSalePrice() != null && memberChange.getSalePrice().compareTo(detail.getSalePrice()) !=0) {
+            return succeed(false);
+        }
+        return succeed(true);
+    }
+
 	@PostMapping("/vipPermissions")
 	@PostMapping("/vipPermissions")
 	@ApiOperation(value = "查询vip权限")
 	@ApiOperation(value = "查询vip权限")
 	public HttpResponseResult<List<SysConfig>> vipPermissions() {
 	public HttpResponseResult<List<SysConfig>> vipPermissions() {

+ 40 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java

@@ -25,6 +25,7 @@ import com.yonge.cooleshow.biz.dal.vo.CheckVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -96,6 +97,27 @@ public class MusicSheetController extends BaseController {
         return succeed(musicSheetService.detail(id, sysUser, ClientEnum.STUDENT,tenantAlbumId));
         return succeed(musicSheetService.detail(id, sysUser, ClientEnum.STUDENT,tenantAlbumId));
     }
     }
 
 
+
+
+    @GetMapping("/detailUse/{id}")
+    @ApiOperation(value = "是否可使用")
+    public HttpResponseResult<MusicSheetWrapper.MusicUse> detailUse(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") String id,
+                                                        @RequestParam(required = false) String tenantAlbumId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            sysUser = null;
+        }
+        MusicSheetDetailVo detail = musicSheetService.detail(id, sysUser, ClientEnum.STUDENT, tenantAlbumId);
+        if (detail == null) {
+            return failed("曲目不存在");
+        }
+
+        MusicSheetWrapper.MusicUse musicUse = new MusicSheetWrapper.MusicUse();
+        musicUse.setBuyed(detail.getBuyed());
+        musicUse.setPlay(detail.getPlay());
+        return succeed(musicUse);
+    }
+
     @ApiOperation(value = "曲目分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
     @ApiOperation(value = "曲目分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
     @PostMapping(value="/list", consumes="application/json", produces="application/json")
     @PostMapping(value="/list", consumes="application/json", produces="application/json")
     public HttpResponseResult<PageInfo<MusicSheetVo>> list(@RequestBody StudentMusicSheetSearch query) {
     public HttpResponseResult<PageInfo<MusicSheetVo>> list(@RequestBody StudentMusicSheetSearch query) {
@@ -329,8 +351,24 @@ public class MusicSheetController extends BaseController {
     @ApiOperation(value = "关联的曲目列表")
     @ApiOperation(value = "关联的曲目列表")
     @GetMapping(value="/queryRelatedList")
     @GetMapping(value="/queryRelatedList")
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
-    	
-    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo.getAlbumId(), queryInfo.getMusicSheetId());
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            return failed("用户信息获取失败");
+        }
+        // 如果是机构学生
+        IPage<MusicSheetVo> musicSheetVoIPage;
+        if (student.getTenantId() !=null && student.getTenantId()>0) {
+            queryInfo.setSubjectId(Long.parseLong(student.getSubjectId()));
+            musicSheetVoIPage =musicSheetService.queryTenantRelatedList(PageUtil.getPage(queryInfo),queryInfo);
+        } else {
+
+            musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo), queryInfo);
+        }
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
     }
     }
 
 

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

@@ -103,9 +103,10 @@ public class UserOrderController extends BaseController {
                 return HttpResponseResult.failed("下单失败");
                 return HttpResponseResult.failed("下单失败");
             }
             }
         } catch (BizException e) {
         } catch (BizException e) {
-            return HttpResponseResult.failed(e.getMessage());
+            log.error("下单失败", e);
+            throw e;
         } catch (Exception e) {
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("下单失败", e);
             return HttpResponseResult.failed("下单失败");
             return HttpResponseResult.failed("下单失败");
         }
         }
     }
     }
@@ -134,7 +135,8 @@ public class UserOrderController extends BaseController {
                 return HttpResponseResult.failed("付款失败");
                 return HttpResponseResult.failed("付款失败");
             }
             }
         } catch (BizException e) {
         } catch (BizException e) {
-            return HttpResponseResult.failed(e.getMessage());
+            log.error("下单失败", e);
+            throw e;
         } catch (Exception e) {
         } catch (Exception e) {
             e.printStackTrace();
             e.printStackTrace();
             return HttpResponseResult.failed("付款失败");
             return HttpResponseResult.failed("付款失败");
@@ -157,7 +159,9 @@ public class UserOrderController extends BaseController {
     })
     })
     public HttpResponseResult<UserOrderVo> getPendingOrder(@ApiIgnore @RequestBody OrderSearch query) {
     public HttpResponseResult<UserOrderVo> getPendingOrder(@ApiIgnore @RequestBody OrderSearch query) {
         if (null == query.getGoodType()
         if (null == query.getGoodType()
-                || (!GoodTypeEnum.VIP.getCode().equals(query.getGoodType()) && null == query.getBizId())) {
+                || (!GoodTypeEnum.VIP.getCode().equals(query.getGoodType())
+            && !GoodTypeEnum.SVIP.getCode().equals(query.getGoodType())
+            && null == query.getBizId())) {
             return HttpResponseResult.failed("参数异常");
             return HttpResponseResult.failed("参数异常");
         }
         }
         SysUser user = sysUserFeignService.queryUserInfo();
         SysUser user = sysUserFeignService.queryUserInfo();
@@ -165,6 +169,7 @@ public class UserOrderController extends BaseController {
             return failed(HttpStatus.FORBIDDEN, "请登录");
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
         }
         query.setUserId(user.getId());
         query.setUserId(user.getId());
+        query.setOrderClient(ClientEnum.STUDENT.name());
         return userOrderService.getPendingOrder(query);
         return userOrderService.getPendingOrder(query);
     }
     }
 
 

+ 3 - 3
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupController.java

@@ -145,7 +145,7 @@ public class ImGroupController extends BaseController {
     @ApiOperation("获取群详情")
     @ApiOperation("获取群详情")
     @PostMapping(value = "/getDetail/{groupId}")
     @PostMapping(value = "/getDetail/{groupId}")
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
     public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
-        ImGroup group = imGroupService.getById(groupId);
+        ImGroup group = imGroupService.getGroupById(groupId);
         if (group == null) {
         if (group == null) {
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
             return failed(HttpStatus.NO_CONTENT, "群组不存在");
         }
         }
@@ -195,7 +195,7 @@ public class ImGroupController extends BaseController {
             return failed("无效的用户ID");
             return failed("无效的用户ID");
         }
         }
 
 
-        ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
+        ImUserFriendVO.ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
         if (Objects.isNull(userFriend)) {
         if (Objects.isNull(userFriend)) {
             return failed("当前好友不存在");
             return failed("当前好友不存在");
         }
         }
@@ -204,7 +204,7 @@ public class ImGroupController extends BaseController {
             userFriend.setFriendType(ClientEnum.STUDENT);
             userFriend.setFriendType(ClientEnum.STUDENT);
         }
         }
 
 
-        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+        return succeed(userFriend);
     }
     }
 
 
     @ApiOperation(value = "转让群主", notes = "转让群主- 传入 ImGroupVo.ImGroupOwner")
     @ApiOperation(value = "转让群主", notes = "转让群主- 传入 ImGroupVo.ImGroupOwner")

+ 4 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImUserFriendController.java

@@ -9,6 +9,7 @@ import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
 import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -90,7 +91,7 @@ public class ImUserFriendController extends BaseController {
             return failed("无效的用户ID");
             return failed("无效的用户ID");
         }
         }
 
 
-        ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
+        ImUserFriendVO.ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
         if (Objects.isNull(userFriend)) {
         if (Objects.isNull(userFriend)) {
             return failed("当前好友不存在");
             return failed("当前好友不存在");
         }
         }
@@ -99,7 +100,8 @@ public class ImUserFriendController extends BaseController {
             userFriend.setFriendType(ClientEnum.STUDENT);
             userFriend.setFriendType(ClientEnum.STUDENT);
         }
         }
 
 
-        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+
+        return succeed(userFriend);
     }
     }
 
 
 }
 }

+ 17 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MemberPriceSettingsController.java

@@ -40,9 +40,26 @@ public class MemberPriceSettingsController extends BaseController {
 		return succeed(memberPriceSettingsService.detail(id)); 
 		return succeed(memberPriceSettingsService.detail(id)); 
 	}
 	}
 
 
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/check/{id}")
+    @ApiOperation(value = "检查会员是否有效", notes = "传入id")
+    public HttpResponseResult<Boolean> check(@PathVariable("id") Long id) {
+        MemberPriceSettingsVo detail = memberPriceSettingsService.detail(id);
+        if (detail == null) {
+            return succeed(false);
+        }else if (Boolean.FALSE.equals(detail.getStatus())) {
+            return succeed(false);
+        }
+        return succeed(true);
+    }
+
 	@PostMapping("/list")
 	@PostMapping("/list")
 	@ApiOperation(value = "查询列表")
 	@ApiOperation(value = "查询列表")
 	public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
 	public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
+		query.setStatus(true);
 		MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
 		MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
 		return succeed(memberPriceVo);
 		return succeed(memberPriceVo);
 	}
 	}

+ 22 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java

@@ -23,6 +23,7 @@ import com.yonge.cooleshow.biz.dal.service.cbs.CbsMusicScoreService;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetShareVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetShareVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.wrapper.MusicSheetWrapper;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.EStatus;
 import com.yonge.cooleshow.common.enums.EStatus;
@@ -89,6 +90,26 @@ public class MusicSheetController extends BaseController {
         return succeed(detail);
         return succeed(detail);
     }
     }
 
 
+
+    @GetMapping("/detailUse/{id}")
+    @ApiOperation(value = "是否可使用")
+    public HttpResponseResult<MusicSheetWrapper.MusicUse> detailUse(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") String id,
+                                                                    @RequestParam(required = false) String tenantAlbumId) {
+        SysUser sysUser = sysUserService.getUser();
+        if (sysUser == null  || sysUser.getId() == null) {
+            sysUser = null;
+        }
+        MusicSheetDetailVo detail = musicSheetService.detail(id, sysUser, ClientEnum.TEACHER, tenantAlbumId);
+        if (detail == null) {
+            return failed("曲目不存在");
+        }
+
+        MusicSheetWrapper.MusicUse musicUse = new MusicSheetWrapper.MusicUse();
+        musicUse.setBuyed(detail.getBuyed());
+        musicUse.setPlay(detail.getPlay());
+        return succeed(musicUse);
+    }
+
     @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
     @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
     @PostMapping(value="/updateRenderFile", consumes="application/json", produces="application/json")
     @PostMapping(value="/updateRenderFile", consumes="application/json", produces="application/json")
     public HttpResponseResult<Object> updateRenderFile(@Valid @RequestBody MusicSheetRenderDto musicSheetRenderDto) {
     public HttpResponseResult<Object> updateRenderFile(@Valid @RequestBody MusicSheetRenderDto musicSheetRenderDto) {
@@ -238,7 +259,7 @@ public class MusicSheetController extends BaseController {
     @GetMapping(value="/queryRelatedList")
     @GetMapping(value="/queryRelatedList")
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
     	
     	
-    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo.getAlbumId(), queryInfo.getMusicSheetId());
+    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo);
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
     }
     }
 
 

+ 25 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/StudentController.java

@@ -5,10 +5,12 @@ import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
 import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
 import com.yonge.cooleshow.biz.dal.service.TenantGroupService;
 import com.yonge.cooleshow.biz.dal.service.TenantGroupService;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.controller.BaseController;
@@ -16,15 +18,20 @@ import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.UserStatusEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -53,6 +60,9 @@ public class StudentController extends BaseController {
     @Autowired
     @Autowired
     private TenantGroupService tenantGroupService;
     private TenantGroupService tenantGroupService;
 
 
+    @Autowired
+    private TeacherService teacherService;
+
 
 
     @ApiOperation(value = "查询指定学员信息-融云token")
     @ApiOperation(value = "查询指定学员信息-融云token")
     @GetMapping("/queryUserById")
     @GetMapping("/queryUserById")
@@ -75,6 +85,21 @@ public class StudentController extends BaseController {
         return succeed(studentService.detail(userId));
         return succeed(studentService.detail(userId));
     }
     }
 
 
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<StudentVo> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        Teacher teacher = teacherService.getById(user.getId());
+        if (Boolean.FALSE.equals(teacher.getCustomerService())) {
+            throw new BizException("权限不足");
+        }
+        StudentVo detail = studentService.detail(id);
+        if (detail != null && detail.getTenantGroupId() != null) {
+            TenantGroup group = tenantGroupService.getById(detail.getTenantGroupId());
+            detail.setTenantGroupName(group == null ? "" : group.getName());
+        }
+        return succeed(detail);
+    }
+
     /**
     /**
      * 查询老师所属机构下所有的学生
      * 查询老师所属机构下所有的学生
      *
      *

+ 28 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherController.java

@@ -7,8 +7,10 @@ import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
 import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
 import com.yonge.cooleshow.biz.dal.entity.TenantUnbindRecord;
 import com.yonge.cooleshow.biz.dal.entity.TenantUnbindRecord;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
 import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
 import com.yonge.cooleshow.biz.dal.service.SubjectService;
 import com.yonge.cooleshow.biz.dal.service.SubjectService;
@@ -30,13 +32,18 @@ import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 import io.swagger.annotations.ApiParam;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -83,6 +90,27 @@ public class TeacherController extends BaseController {
         return teacherService.queryUserInfo(user.getId());
         return teacherService.queryUserInfo(user.getId());
     }
     }
 
 
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<TeacherVo> detail(@PathVariable("id") Long userId) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        Teacher teacher = teacherService.getById(user.getId());
+        if (Boolean.FALSE.equals(teacher.getCustomerService())) {
+            throw new BizException("权限不足");
+        }
+
+        TeacherVo detail = teacherService.findTeacherDetailInfo(userId);
+        if (null != detail && !CollectionUtils.isEmpty(detail.getStyleVideo())) {
+            List<TeacherStyleVideo> styleVideo = detail.getStyleVideo();
+            List<TeacherStyleVideo> collect = styleVideo.stream().filter(o -> AuthStatusEnum.PASS.equals(o.getAuthStatus())).collect(Collectors.toList());
+            detail.setStyleVideo(collect);
+        }
+        return succeed(detail);
+    }
+
     @ApiOperation(value = "开通直播")
     @ApiOperation(value = "开通直播")
     @GetMapping("/openLive")
     @GetMapping("/openLive")
     public HttpResponseResult<Boolean> openLive() {
     public HttpResponseResult<Boolean> openLive() {

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

@@ -215,8 +215,8 @@ public class TeacherCourseScheduleController extends BaseController {
         if (user == null || null == user.getId()) {
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
         }
-        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
-        return succeed();
+        String message = courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed(message);
     }
     }
 
 
     @ApiOperation("根据月份查询消耗时长")
     @ApiOperation("根据月份查询消耗时长")

+ 33 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserOrderController.java

@@ -12,6 +12,7 @@ import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.entity.UserOrder;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
 import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
 import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
 import com.yonge.cooleshow.biz.dal.service.UserOrderService;
 import com.yonge.cooleshow.biz.dal.service.UserOrderService;
 import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
 import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
@@ -137,6 +138,38 @@ public class UserOrderController extends BaseController {
         }
         }
     }
     }
 
 
+
+    @ApiOperation(value = "通过业务id查询用户正在交易中的订单")
+    @PostMapping("/getPendingOrder")
+    @ApiImplicitParams({
+        @ApiImplicitParam(
+            name = "goodType",
+            value = "订单类型:  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名",
+            paramType = "query", dataType = "String", required = true
+        ),
+        @ApiImplicitParam(
+            name = "bizId",
+            value = "业务id 直播课、陪练课购买为课程组id;陪练课为老师id;单曲点播传曲子id",
+            paramType = "query", dataType = "Long"
+        )
+    })
+    public HttpResponseResult<UserOrderVo> getPendingOrder(@ApiIgnore @RequestBody OrderSearch query) {
+        if (null == query.getGoodType()
+            || (!GoodTypeEnum.VIP.getCode().equals(query.getGoodType())
+            && !GoodTypeEnum.SVIP.getCode().equals(query.getGoodType())
+            && null == query.getBizId())) {
+            return HttpResponseResult.failed("参数异常");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        query.setOrderClient(ClientEnum.TEACHER.name());
+        return userOrderService.getPendingOrder(query);
+    }
+
+
     @ApiOperation(value = "取消订单")
     @ApiOperation(value = "取消订单")
     @PostMapping("/orderCancel")
     @PostMapping("/orderCancel")
     @ApiImplicitParams({
     @ApiImplicitParams({

+ 1 - 1
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java

@@ -177,7 +177,7 @@ public class MusicSheetController extends BaseController {
     @GetMapping(value="/queryRelatedList")
     @GetMapping(value="/queryRelatedList")
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
     public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
     	
     	
-    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo.getAlbumId(), queryInfo.getMusicSheetId());
+    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo), queryInfo);
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
     }
     }
 }
 }

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

@@ -23,6 +23,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.HttpStatus;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.validation.annotation.Validated;
@@ -211,8 +212,8 @@ public class WebCourseScheduleController extends BaseController {
         if (user == null || null == user.getId()) {
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
         }
-        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
-        return succeed();
+        String message = courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed(message);
     }
     }
 
 
     @ApiOperation("根据月份查询消耗时长")
     @ApiOperation("根据月份查询消耗时长")

+ 2 - 2
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/config/CustomerServiceConfig.java

@@ -16,8 +16,8 @@ import java.io.Serializable;
 @Component
 @Component
 public class CustomerServiceConfig implements Serializable {
 public class CustomerServiceConfig implements Serializable {
 
 
-    @Value("${app.customer.service:17740683946}")
-    private String customerService;
+//    @Value("${app.customer.service:17740683946}")
+//    private String customerService;
     @Value("${app.customer.message:}")
     @Value("${app.customer.message:}")
     private String customerMessage;
     private String customerMessage;
     @Value("${app.customer.title:}")
     @Value("${app.customer.title:}")

+ 3 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/dal/dao/SysUserDao.java

@@ -185,4 +185,7 @@ public interface SysUserDao extends BaseDAO<Long, SysUser> {
     void updateStudentHideFlag(@Param("userId") Long userId, @Param("hideFlag") int hideFlag);
     void updateStudentHideFlag(@Param("userId") Long userId, @Param("hideFlag") int hideFlag);
 
 
     void updateAvatar(@Param("clientId") String clientId, @Param("avatar") String avatar,@Param("id") Long id);
     void updateAvatar(@Param("clientId") String clientId, @Param("avatar") String avatar,@Param("id") Long id);
+
+    SysUser getCustomerServiceByFriendLeast();
+
 }
 }

+ 5 - 13
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/service/impl/SysUserServiceImpl.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.auth.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
 import com.yonge.cooleshow.api.feign.AdminFeignService;
+import com.yonge.cooleshow.api.feign.TeacherFeignService;
 import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.api.feign.dto.UserFriendInfoVO;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.QRLoginDto;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
@@ -218,24 +219,15 @@ public class SysUserServiceImpl extends BaseServiceImpl<Long, SysUser> implement
 
 
             ThreadPool.getExecutor().submit(() -> {
             ThreadPool.getExecutor().submit(() -> {
 
 
-                String customerService = customerServiceConfig.getCustomerService();
-                if (StringUtils.isNotEmpty(customerService)) {
-
-                    List<String> collect = Arrays.stream(customerService.split(",")).collect(Collectors.toList());
-
-                    Random rand = new Random();
-                    String mobile = collect.get(rand.nextInt(collect.size()));
-
-                    // 系统客服好友
-                    SysUser friend = sysUserDao.queryByPhone(mobile);
-
+                SysUser customerService = sysUserDao.getCustomerServiceByFriendLeast();
+                if (customerService != null) {
                     // 发送添加系统客服好友消息
                     // 发送添加系统客服好友消息
                     HttpResponseResult<Boolean> result = adminFeignService.customerService(UserFriendInfoVO.builder()
                     HttpResponseResult<Boolean> result = adminFeignService.customerService(UserFriendInfoVO.builder()
                             .userId(sysUser.getId())
                             .userId(sysUser.getId())
                             .clientType(clientType)
                             .clientType(clientType)
-                            .friendIds(Lists.newArrayList(friend.getId()))
+                            .friendIds(Lists.newArrayList(customerService.getId()))
                             .build());
                             .build());
-                    log.info("sendSysCustomerServiceFriendMessage mobile={}, ret={}", mobile, JSON.toJSONString(result));
+                    log.info("sendSysCustomerServiceFriendMessage mobile={}, ret={}", customerService.getPhone(), JSON.toJSONString(result));
                 }
                 }
 
 
             });
             });

+ 17 - 0
cooleshow-auth/auth-server/src/main/resources/config/mybatis/SysUserMapper.xml

@@ -382,4 +382,21 @@
             update sys_user set avatar_ = #{avatar} where id_ = #{id}
             update sys_user set avatar_ = #{avatar} where id_ = #{id}
         </if>
         </if>
     </update>
     </update>
+
+    <select id="getCustomerServiceByFriendLeast" resultMap="SysUser">
+        select m.*
+        from (SELECT te.user_id_,
+                     count(distinct iuf.friend_id_) friends
+              from teacher te
+                       left join sys_user su on te.user_id_ = su.id_
+                       left join im_user_friend iuf on te.user_id_ = iuf.user_id_
+              where te.lock_flag_ = 0
+                and te.customer_service_ = 1
+                and su.del_flag_ = 0
+                and su.lock_flag_ = 0
+              group by te.user_id_
+              order by friends
+              limit 1) t
+                 left join sys_user m on m.id_ = t.user_id_
+    </select>
 </mapper>
 </mapper>

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

@@ -110,6 +110,7 @@ public interface SysConfigConstant {
      * @updateTime 2022/4/20 11:43
      * @updateTime 2022/4/20 11:43
      */
      */
     String GOOD_LOGO_VIP = "good_logo_vip";
     String GOOD_LOGO_VIP = "good_logo_vip";
+    String GOOD_LOGO_SVIP = "good_logo_svip";
     /***
     /***
      * 商品视频课图片
      * 商品视频课图片
      * @author liweifan
      * @author liweifan
@@ -429,4 +430,19 @@ public interface SysConfigConstant {
      * 草稿保存时长
      * 草稿保存时长
      */
      */
     String USER_MUSIC_DRAFT_TIME = "user_music_draft_time";
     String USER_MUSIC_DRAFT_TIME = "user_music_draft_time";
+
+    /**
+     * 添加客服好友时,客服发送消息
+     */
+    String CUSTOMER_SERVICE_ADD_MSG = "customer_service_add_msg";
+
+    /**
+     * 添加客服好友时,客服发送消息标题
+     */
+    String CUSTOMER_SERVICE_ADD_MSG_TITLE = "customer_service_add_msg_title";
+
+    /**
+     * 群成员人数限制
+     */
+    String GROUP_MEMBER_LIMIT = "group_member_limit";
 }
 }

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

@@ -13,6 +13,7 @@ public enum RewardTypeEnum implements BaseEnum<String, RewardTypeEnum> {
 
 
     ACTUAL("实物"),
     ACTUAL("实物"),
     VIP("小酷AI会员"),
     VIP("小酷AI会员"),
+    SVIP("小酷AISVIP会员"),
     PIANO_ROOM("琴房时长"),
     PIANO_ROOM("琴房时长"),
     COUPON("优惠券"),
     COUPON("优惠券"),
     ;
     ;

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

@@ -22,6 +22,7 @@ public enum UnitEnum implements BaseEnum<String, UnitEnum> {
 //    YEAR("年"),
 //    YEAR("年"),
     QUARTERLY("季度"),
     QUARTERLY("季度"),
     YEAR_HALF("半年"),
     YEAR_HALF("半年"),
+    PERPETUAL("永久"),
     ;
     ;
 
 
     @EnumValue
     @EnumValue

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

@@ -10,6 +10,7 @@ import lombok.Getter;
 public enum EPaymentType {
 public enum EPaymentType {
 
 
     VIP("开通会员"),
     VIP("开通会员"),
+    SVIP("开通会员 SVIP"),
     PRACTICE("陪练课购买"),
     PRACTICE("陪练课购买"),
     LIVE("直播课购买"),
     LIVE("直播课购买"),
     VIDEO("视频课购买"),
     VIDEO("视频课购买"),

+ 13 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseScheduleStudentPaymentDao.java

@@ -30,7 +30,7 @@ public interface CourseScheduleStudentPaymentDao extends BaseMapper<CourseSchedu
      * @author zx
      * @author zx
      * @date 2022/3/23 16:18
      * @date 2022/3/23 16:18
      */
      */
-    Set<Long> queryStudentIds(@Param("courseGroupId") Long courseGroupId,
+    List<Long> queryStudentIds(@Param("courseGroupId") Long courseGroupId,
                               @Param("courseGroupType") String courseGroupType);
                               @Param("courseGroupType") String courseGroupType);
 
 
     /**
     /**
@@ -87,5 +87,17 @@ public interface CourseScheduleStudentPaymentDao extends BaseMapper<CourseSchedu
     List<CourseScheduleStudentVo> selectUser();
     List<CourseScheduleStudentVo> selectUser();
 
 
     List<BasicUserInfoDto> queryNoJoinStu(@Param("scheduleId") String scheduleId, @Param("studentIds") List<String> studentIds);
     List<BasicUserInfoDto> queryNoJoinStu(@Param("scheduleId") String scheduleId, @Param("studentIds") List<String> studentIds);
+
+    /**
+     * 更新用户入群状态
+     * @param courseGroupId 课程组id
+     * @param courseGroupType 课程组类型
+     * @param groupJoin 入群状态
+     * @param studentIds 学员id
+     */
+    void updateGroupJoinStatus(@Param("courseGroupId") Long courseGroupId,
+                               @Param("courseGroupType") String courseGroupType,
+                               @Param("groupJoin") Boolean groupJoin,
+                               @Param("studentIds") List<Long> studentIds);
 }
 }
 
 

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

@@ -23,5 +23,7 @@ public interface ImUserFriendDao extends BaseMapper<ImUserFriend> {
 
 
     void delStudentFriendByTenantId(@Param("tenantId") Long tenantId,@Param("userId") Long userId ,
     void delStudentFriendByTenantId(@Param("tenantId") Long tenantId,@Param("userId") Long userId ,
                                     @Param("clientType") String clientType);
                                     @Param("clientType") String clientType);
+
+    List<ImUserFriend> queryExistCustomerServiceFriend(@Param("userIds") String userIds, @Param("clientType") String clientType);
 }
 }
 
 

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

@@ -213,4 +213,6 @@ public interface MusicSheetDao extends BaseMapper<MusicSheet> {
     MusicSheet get(Long id);
     MusicSheet get(Long id);
 
 
     IPage<MusicSheet> selectSyncPage(Page<Object> objectPage);
     IPage<MusicSheet> selectSyncPage(Page<Object> objectPage);
+
+    IPage<MusicSheetVo> queryTenantRelatedList(@Param("page") IPage<Object> page, @Param("queryInfo") MusicSheetRelatedQueryInfo queryInfo);
 }
 }

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/StudentDao.java

@@ -82,4 +82,5 @@ public interface StudentDao extends BaseMapper<Student> {
     Integer queryStudentCounts(@Param("id") Long id);
     Integer queryStudentCounts(@Param("id") Long id);
 
 
     List<StudentWrapper.UserCount> countStudentByTenantGroupIds(@Param("tenantId") Long tenantId, @Param("groupIdList") List<Long> groupIdList);
     List<StudentWrapper.UserCount> countStudentByTenantGroupIds(@Param("tenantId") Long tenantId, @Param("groupIdList") List<Long> groupIdList);
+
 }
 }

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/TeacherDao.java

@@ -16,6 +16,7 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 
 
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 
 
 public interface TeacherDao extends BaseMapper<Teacher> {
 public interface TeacherDao extends BaseMapper<Teacher> {
@@ -115,4 +116,8 @@ public interface TeacherDao extends BaseMapper<Teacher> {
     List<TenantInfoWrapper.UserCount> countTeacherByTenantIds(@Param("tenantIdList") List<Long> tenantIdList);
     List<TenantInfoWrapper.UserCount> countTeacherByTenantIds(@Param("tenantIdList") List<Long> tenantIdList);
 
 
     Integer queryTeacherCounts(@Param("id") Long id);
     Integer queryTeacherCounts(@Param("id") Long id);
+
+    Teacher getCustomerServiceByFriendLeast();
+
+    List<TeacherWrapper.TeacherFriend> getCustomerServiceFriendNums();
 }
 }

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/VipCardRecordDao.java

@@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Param;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
@@ -58,4 +60,6 @@ public interface VipCardRecordDao extends BaseMapper<VipCardRecord> {
      * @return
      * @return
      */
      */
     IPage<VipRecordVo> selectVipRecord(@Param("page") IPage<VipRecordVo> page, @Param("param") VipRecordSearch param);
     IPage<VipRecordVo> selectVipRecord(@Param("page") IPage<VipRecordVo> page, @Param("param") VipRecordSearch param);
+
+    List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(@Param("userIdList") List<Long> userIdList ,@Param("clientType") String clientType);
 }
 }

+ 8 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/BasicUserInfo.java

@@ -3,6 +3,8 @@ package com.yonge.cooleshow.biz.dal.dto;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import lombok.Data;
 
 
+import java.util.Date;
+
 /**
 /**
 * @description: 用户基本信息
 * @description: 用户基本信息
 * @author zx
 * @author zx
@@ -27,4 +29,10 @@ public class BasicUserInfo {
 
 
     @ApiModelProperty("手机号")
     @ApiModelProperty("手机号")
     private String phone;
     private String phone;
+
+    @ApiModelProperty("性别")
+    private Integer gender;
+
+    @ApiModelProperty("生日")
+    private Date birthdate;
 }
 }

+ 44 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/OrderReq.java

@@ -32,7 +32,7 @@ public class OrderReq {
     @ApiModelProperty(value = "订单名称 ", required = true)
     @ApiModelProperty(value = "订单名称 ", required = true)
     private String orderName;
     private String orderName;
     @NotNull(message = "订单类型不能为空")
     @NotNull(message = "订单类型不能为空")
-    @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
+    @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  SVIP:SVIP PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
     private OrderTypeEnum orderType;
     private OrderTypeEnum orderType;
     @ApiModelProperty(value = "订单描述信息 ")
     @ApiModelProperty(value = "订单描述信息 ")
     private String orderDesc;
     private String orderDesc;
@@ -71,10 +71,21 @@ public class OrderReq {
         private GoodTypeEnum goodType;
         private GoodTypeEnum goodType;
         @ApiModelProperty("商品名称 ")
         @ApiModelProperty("商品名称 ")
         private String goodName;
         private String goodName;
+
+        @ApiModelProperty(value = "下单客户端 ",hidden = true)
+        private ClientEnum orderClient;
+        @ApiModelProperty(value = "vip剩余天数")
+        private Integer vipEndDays;
+
+        @ApiModelProperty(value = "商品数量")
+        private Integer goodsNum = 1;
+
         @ApiModelProperty(value = "优惠券id")
         @ApiModelProperty(value = "优惠券id")
         private Long couponId;
         private Long couponId;
         @ApiModelProperty(value = "业务内容")
         @ApiModelProperty(value = "业务内容")
         private Object bizContent;
         private Object bizContent;
+        @ApiModelProperty(value = "业务价格")
+        private BigDecimal bizPrice;
         @ApiModelProperty(value = "调用业务创建方法返回", hidden = true)
         @ApiModelProperty(value = "调用业务创建方法返回", hidden = true)
         private OrderCreateRes createRes;
         private OrderCreateRes createRes;
         @ApiModelProperty(value = "订单金额", required = true)
         @ApiModelProperty(value = "订单金额", required = true)
@@ -85,6 +96,38 @@ public class OrderReq {
         // 透传订单类型
         // 透传订单类型
         private OrderTypeEnum orderType;
         private OrderTypeEnum orderType;
 
 
+        public BigDecimal getBizPrice() {
+            return bizPrice;
+        }
+
+        public void setBizPrice(BigDecimal bizPrice) {
+            this.bizPrice = bizPrice;
+        }
+
+        public Integer getGoodsNum() {
+            return goodsNum;
+        }
+
+        public void setGoodsNum(Integer goodsNum) {
+            this.goodsNum = goodsNum;
+        }
+
+        public ClientEnum getOrderClient() {
+            return orderClient;
+        }
+
+        public void setOrderClient(ClientEnum orderClient) {
+            this.orderClient = orderClient;
+        }
+
+        public Integer getVipEndDays() {
+            return vipEndDays;
+        }
+
+        public void setVipEndDays(Integer vipEndDays) {
+            this.vipEndDays = vipEndDays;
+        }
+
         public BigDecimal getActualPrice() {
         public BigDecimal getActualPrice() {
             return actualPrice;
             return actualPrice;
         }
         }

+ 3 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/req/TeacherSubmitReq.java

@@ -65,6 +65,9 @@ public class TeacherSubmitReq implements Serializable {
     @ApiModelProperty(value = "后台修改人",hidden = true)
     @ApiModelProperty(value = "后台修改人",hidden = true)
     private Long updateBy;
     private Long updateBy;
 
 
+    @ApiModelProperty("是否客服")
+    private Boolean customerService;
+
     public Long getUserId() {
     public Long getUserId() {
         return userId;
         return userId;
     }
     }

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

@@ -1,13 +1,16 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 package com.yonge.cooleshow.biz.dal.dto.search;
 
 
+import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
 
 /**
 /**
  * @Author: liweifan
  * @Author: liweifan
  * @Data: 2022-04-25 14:34:49
  * @Data: 2022-04-25 14:34:49
  */
  */
+@Data
 @ApiModel(value = "MemberPriceSettingsSearch对象", description = "查询对象")
 @ApiModel(value = "MemberPriceSettingsSearch对象", description = "查询对象")
 public class MemberPriceSettingsSearch extends QueryInfo{
 public class MemberPriceSettingsSearch extends QueryInfo{
 	private static final long serialVersionUID = 1L;
 	private static final long serialVersionUID = 1L;
@@ -18,19 +21,10 @@ public class MemberPriceSettingsSearch extends QueryInfo{
 	@ApiModelProperty("活动id")
 	@ApiModelProperty("活动id")
 	private Long  activityId;
 	private Long  activityId;
 
 
-	public Long getActivityId() {
-		return activityId;
-	}
+	@ApiModelProperty("true:启用,false:停用")
+	private Boolean status;
 
 
-	public void setActivityId(Long activityId) {
-		this.activityId = activityId;
-	}
+	@ApiModelProperty("VIP,SVIP")
+	private EVipType vipType;
 
 
-	public Long getUserId() {
-		return userId;
-	}
-
-	public void setUserId(Long userId) {
-		this.userId = userId;
-	}
 }
 }

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

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 package com.yonge.cooleshow.biz.dal.dto.search;
 
 
+import com.yonge.cooleshow.biz.dal.enums.MusicSheetTypeEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.toolset.base.page.QueryInfo;
 
 
 public class MusicSheetRelatedQueryInfo extends QueryInfo {
 public class MusicSheetRelatedQueryInfo extends QueryInfo {
@@ -8,7 +9,27 @@ public class MusicSheetRelatedQueryInfo extends QueryInfo {
 	
 	
 	private Long musicSheetId;
 	private Long musicSheetId;
 
 
-	public Long getAlbumId() {
+    private Long subjectId;
+
+    private MusicSheetTypeEnum musicSheetType;
+
+    public MusicSheetTypeEnum getMusicSheetType() {
+        return musicSheetType;
+    }
+
+    public void setMusicSheetType(MusicSheetTypeEnum musicSheetType) {
+        this.musicSheetType = musicSheetType;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public Long getAlbumId() {
 		return albumId;
 		return albumId;
 	}
 	}
 
 

+ 23 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetSearch.java

@@ -106,6 +106,29 @@ public class MusicSheetSearch  extends QueryInfo{
     @ApiModelProperty("指定关联专辑的曲目排在最后")
     @ApiModelProperty("指定关联专辑的曲目排在最后")
     private Long sortByAlbumIdDesc;
     private Long sortByAlbumIdDesc;
 
 
+
+    @ApiModelProperty(value = "不包含曲目ID",hidden = true)
+    private List<Long> excludeMusicIds;
+
+    @ApiModelProperty(value = "必须要匹配声部ID")
+    private List<Long> mustMatchSubjectIds;
+
+    public List<Long> getExcludeMusicIds() {
+        return excludeMusicIds;
+    }
+
+    public void setExcludeMusicIds(List<Long> excludeMusicIds) {
+        this.excludeMusicIds = excludeMusicIds;
+    }
+
+    public List<Long> getMustMatchSubjectIds() {
+        return mustMatchSubjectIds;
+    }
+
+    public void setMustMatchSubjectIds(List<Long> mustMatchSubjectIds) {
+        this.mustMatchSubjectIds = mustMatchSubjectIds;
+    }
+
     public SourceTypeEnum getProviderType() {
     public SourceTypeEnum getProviderType() {
         return providerType;
         return providerType;
     }
     }

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

@@ -22,7 +22,7 @@ public class OrderSearch extends QueryInfo{
 	@ApiModelProperty("下单应用:STUDENT 学生端 TEACHER 老师端")
 	@ApiModelProperty("下单应用:STUDENT 学生端 TEACHER 老师端")
 	private String orderClient;
 	private String orderClient;
 
 
-	@ApiModelProperty("交易类型:  VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名(多选用,分割)")
+	@ApiModelProperty("交易类型:  VIP、开通会员  SVIP、开通会员 PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名(多选用,分割)")
 	private String orderType;
 	private String orderType;
 
 
 	@ApiModelProperty("订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭 FAIL 支付失败 (多选用,分割)")
 	@ApiModelProperty("订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭 FAIL 支付失败 (多选用,分割)")

+ 13 - 9
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/StudentSearch.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 package com.yonge.cooleshow.biz.dal.dto.search;
 
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
 import com.yonge.cooleshow.biz.dal.enums.GenderEnum;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -31,8 +32,8 @@ public class StudentSearch extends QueryInfo{
     @ApiModelProperty(value = "0-正常, 1-锁定")
     @ApiModelProperty(value = "0-正常, 1-锁定")
     private UserLockFlag lockFlag;
     private UserLockFlag lockFlag;
     private YesOrNoEnum delFlag;
     private YesOrNoEnum delFlag;
-    @ApiModelProperty(value = "是否会员 0否 1是")
-    private YesOrNoEnum isVip;
+//    @ApiModelProperty(value = "是否会员 0否 1是")
+//    private YesOrNoEnum isVip;
 
 
     @ApiModelProperty(value = "是否练习 0否 1是")
     @ApiModelProperty(value = "是否练习 0否 1是")
     private YesOrNoEnum trainFlag;
     private YesOrNoEnum trainFlag;
@@ -80,6 +81,9 @@ public class StudentSearch extends QueryInfo{
     @ApiModelProperty("机构购买专辑的购买记录ID")
     @ApiModelProperty("机构购买专辑的购买记录ID")
     private Long tenantAlbumPurchaseId;
     private Long tenantAlbumPurchaseId;
 
 
+    @ApiModelProperty("用户会员类型")
+    private EUserVipType vipType;
+
     @ApiModelProperty(value = "手机号码列表", hidden = true)
     @ApiModelProperty(value = "手机号码列表", hidden = true)
     private List<String> phoneList = new ArrayList<>();
     private List<String> phoneList = new ArrayList<>();
 
 
@@ -138,13 +142,13 @@ public class StudentSearch extends QueryInfo{
         this.lockFlag = lockFlag;
         this.lockFlag = lockFlag;
     }
     }
 
 
-    public YesOrNoEnum getIsVip() {
-        return isVip;
-    }
-
-    public void setIsVip(Integer isVip) {
-        this.isVip = YesOrNoEnum.valueOf(isVip);
-    }
+//    public YesOrNoEnum getIsVip() {
+//        return isVip;
+//    }
+//
+//    public void setIsVip(Integer isVip) {
+//        this.isVip = YesOrNoEnum.valueOf(isVip);
+//    }
 
 
     public Date getStartTime() {
     public Date getStartTime() {
         return startTime;
         return startTime;

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

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 package com.yonge.cooleshow.biz.dal.dto.search;
 
 
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -32,8 +33,8 @@ public class TeacherSearch extends QueryInfo{
     
     
     private YesOrNoEnum delFlag;
     private YesOrNoEnum delFlag;
     
     
-    @ApiModelProperty(value = "是否会员(0-否 1-是)")
-    private Integer isVip;
+//    @ApiModelProperty(value = "是否会员(0-否 1-是)")
+//    private Integer isVip;
     
     
     @ApiModelProperty("用户状态")
     @ApiModelProperty("用户状态")
     private String userStatus;
     private String userStatus;
@@ -78,6 +79,12 @@ public class TeacherSearch extends QueryInfo{
 	@ApiModelProperty("老师ID")
 	@ApiModelProperty("老师ID")
 	private Long userId;
 	private Long userId;
 
 
+	@ApiModelProperty("用户会员类型")
+	private EUserVipType vipType;
+
+	@ApiModelProperty("是否客服")
+	private Boolean customerService;
+
 	@ApiModelProperty(value = "排序方式, 默认 create_time_ desc", hidden = true)
 	@ApiModelProperty(value = "排序方式, 默认 create_time_ desc", hidden = true)
 	private String orderBy;
 	private String orderBy;
 	public YesOrNoEnum getTrainFlag() {
 	public YesOrNoEnum getTrainFlag() {

+ 23 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/VipRecordSearch.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.biz.dal.dto.search;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
@@ -45,6 +46,12 @@ public class VipRecordSearch extends QueryInfo {
     @ApiModelProperty("来源类型 : ACTIVITY :活动 ,ORDER:订单 PLATFORM:平台")
     @ApiModelProperty("来源类型 : ACTIVITY :活动 ,ORDER:订单 PLATFORM:平台")
     private SourceTypeEnum sourceType;
     private SourceTypeEnum sourceType;
 
 
+    @ApiModelProperty(value = "是否展示1:展示,0:隐藏",hidden = true)
+    private Boolean displayFlag;
+
+    @ApiModelProperty("会员类型")
+    private EVipType vipType;
+
     public SourceTypeEnum getSourceType() {
     public SourceTypeEnum getSourceType() {
         return sourceType;
         return sourceType;
     }
     }
@@ -94,4 +101,20 @@ public class VipRecordSearch extends QueryInfo {
     public void setSearch(String search) {
     public void setSearch(String search) {
         this.search = search;
         this.search = search;
     }
     }
+
+    public Boolean getDisplayFlag() {
+        return displayFlag;
+    }
+
+    public void setDisplayFlag(Boolean displayFlag) {
+        this.displayFlag = displayFlag;
+    }
+
+    public EVipType getVipType() {
+        return vipType;
+    }
+
+    public void setVipType(EVipType vipType) {
+        this.vipType = vipType;
+    }
 }
 }

+ 5 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/CourseScheduleStudentPayment.java

@@ -65,5 +65,10 @@ public class CourseScheduleStudentPayment implements Serializable {
     @ApiModelProperty(value = "类型 practice陪练课 live直播课")
     @ApiModelProperty(value = "类型 practice陪练课 live直播课")
     private String courseType;
     private String courseType;
 
 
+    @TableField(value = "group_join_")
+    @ApiModelProperty("入群标记")
+    private Boolean groupJoin;
+
+
 }
 }
 
 

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ImGroup.java

@@ -75,6 +75,10 @@ public class ImGroup implements Serializable {
     @ApiModelProperty(value = "群聊配置")
     @ApiModelProperty(value = "群聊配置")
     private String configJson;
     private String configJson;
 
 
+    @TableField(exist = false) // 不映射数据库字段,返回群成员人数限制
+    @ApiModelProperty("群成员人数限制")
+    private Integer groupMemberLimit;
+
     public Long getCourseGroupId() {
     public Long getCourseGroupId() {
         return courseGroupId;
         return courseGroupId;
     }
     }
@@ -178,5 +182,13 @@ public class ImGroup implements Serializable {
     public void setConfigJson(String configJson) {
     public void setConfigJson(String configJson) {
         this.configJson = configJson;
         this.configJson = configJson;
     }
     }
+
+    public Integer getGroupMemberLimit() {
+        return groupMemberLimit;
+    }
+
+    public void setGroupMemberLimit(Integer groupMemberLimit) {
+        this.groupMemberLimit = groupMemberLimit;
+    }
 }
 }
 
 

+ 12 - 58
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MemberPriceSettings.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import com.yonge.cooleshow.biz.dal.enums.PeriodEnum;
 import com.yonge.cooleshow.biz.dal.enums.PeriodEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
@@ -11,11 +12,13 @@ import io.swagger.annotations.ApiModelProperty;
 import java.io.Serializable;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.format.annotation.DateTimeFormat;
 
 
 import javax.validation.constraints.PositiveOrZero;
 import javax.validation.constraints.PositiveOrZero;
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 
 
+@Data
 @TableName("member_price_settings")
 @TableName("member_price_settings")
 @ApiModel(value = "MemberPriceSettings对象", description = "")
 @ApiModel(value = "MemberPriceSettings对象", description = "")
 public class MemberPriceSettings implements Serializable {
 public class MemberPriceSettings implements Serializable {
@@ -50,68 +53,19 @@ public class MemberPriceSettings implements Serializable {
 	@TableField(value = "update_by_")
 	@TableField(value = "update_by_")
 	private Long updateBy;
 	private Long updateBy;
 
 
-	public Long getId() {
-		return id;
-	}
 
 
-	public void setId(Long id) {
-		this.id = id;
-	}
+    @ApiModelProperty("状态 1:启用 0:停用 ")
+    @TableField(value = "status_")
+    private Boolean status;
 
 
-	public PeriodEnum getPeriod() {
-		return period;
-	}
 
 
-	public void setPeriod(PeriodEnum period) {
-		this.period = period;
-	}
+    @ApiModelProperty("描述文案")
+    @TableField(value = "desc_")
+    private String desc;
 
 
-	public BigDecimal getSalePrice() {
-		return salePrice;
-	}
 
 
-	public void setSalePrice(BigDecimal salePrice) {
-		this.salePrice = salePrice;
-	}
-
-	public BigDecimal getOriginalPrice() {
-		return originalPrice;
-	}
-
-	public void setOriginalPrice(BigDecimal originalPrice) {
-		this.originalPrice = originalPrice;
-	}
-
-	public Date getCreateTime() {
-		return createTime;
-	}
-
-	public void setCreateTime(Date createTime) {
-		this.createTime = createTime;
-	}
-
-	public Date getUpdateTime() {
-		return updateTime;
-	}
-
-	public void setUpdateTime(Date updateTime) {
-		this.updateTime = updateTime;
-	}
-
-	public Long getCreateBy() {
-		return createBy;
-	}
-
-	public void setCreateBy(Long createBy) {
-		this.createBy = createBy;
-	}
-
-	public Long getUpdateBy() {
-		return updateBy;
-	}
-
-	public void setUpdateBy(Long updateBy) {
-		this.updateBy = updateBy;
-	}
 
 
+    @ApiModelProperty("会员类型")
+    @TableField(value = "vip_type_")
+    private EVipType vipType;
 }
 }

+ 16 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/StudentTime.java

@@ -25,6 +25,13 @@ public class StudentTime implements Serializable {
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date firstVipTime;
     private Date firstVipTime;
+
+
+    @ApiModelProperty("第一次购买svip时间 ")
+    @TableField(value = "first_svip_time_")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date firstSvipTime;
     @ApiModelProperty("第一次购买陪练课时间 ")
     @ApiModelProperty("第一次购买陪练课时间 ")
     @TableField(value = "first_practice_time_")
     @TableField(value = "first_practice_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@@ -65,6 +72,15 @@ public class StudentTime implements Serializable {
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date firstActivityTime;
     private Date firstActivityTime;
 
 
+
+    public Date getFirstSvipTime() {
+        return firstSvipTime;
+    }
+
+    public void setFirstSvipTime(Date firstSvipTime) {
+        this.firstSvipTime = firstSvipTime;
+    }
+
     public Date getFirstActivityTime() {
     public Date getFirstActivityTime() {
         return firstActivityTime;
         return firstActivityTime;
     }
     }

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

@@ -251,6 +251,10 @@ public class Teacher implements Serializable {
     @TableField(value = "im_device_id_")
     @TableField(value = "im_device_id_")
     private String imDeviceId;
     private String imDeviceId;
 
 
+    @ApiModelProperty("是否是客服")
+    @TableField(value = "customer_service_")
+    private Boolean customerService;
+
     public ESettlementFrom getSettlementFrom() {
     public ESettlementFrom getSettlementFrom() {
         return settlementFrom;
         return settlementFrom;
     }
     }

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

@@ -95,4 +95,9 @@ public class UserOrderDetail implements Serializable {
     @TableField(value = "tenant_group_album_id_")
     @TableField(value = "tenant_group_album_id_")
     private Long tenantGroupAlbumId;
     private Long tenantGroupAlbumId;
 
 
+
+    @ApiModelProperty("业务数据")
+    @TableField(value = "biz_json_")
+    private String bizJson;
+
 }
 }

+ 27 - 130
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/VipCardRecord.java

@@ -4,20 +4,20 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.PeriodEnum;
-import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.*;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import io.swagger.annotations.ApiModelProperty;
 
 
 import java.io.Serializable;
 import java.io.Serializable;
 import java.util.Date;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
 import org.springframework.format.annotation.DateTimeFormat;
 import org.springframework.format.annotation.DateTimeFormat;
 
 
 /**
 /**
  * 购买会员卡记录表
  * 购买会员卡记录表
  */
  */
+@Data
 @TableName("vip_card_record")
 @TableName("vip_card_record")
 @ApiModel(value = "VipCardRecord对象", description = "购买会员卡记录表")
 @ApiModel(value = "VipCardRecord对象", description = "购买会员卡记录表")
 public class VipCardRecord implements Serializable {
 public class VipCardRecord implements Serializable {
@@ -90,131 +90,28 @@ public class VipCardRecord implements Serializable {
     @TableField(value = "reason_")
     @TableField(value = "reason_")
     private String reason;
     private String reason;
 
 
-    public Long getCreateBy() {
-        return createBy;
-    }
-
-    public void setCreateBy(Long createBy) {
-        this.createBy = createBy;
-    }
-
-    public String getReason() {
-        return reason;
-    }
-
-    public void setReason(String reason) {
-        this.reason = reason;
-    }
-
-    public Integer getTimes() {
-        return times;
-    }
-
-    public void setTimes(Integer times) {
-        this.times = times;
-    }
-
-    public PeriodEnum getType() {
-        return type;
-    }
-
-    public void setType(PeriodEnum type) {
-        this.type = type;
-    }
-
-    public SourceTypeEnum getSourceType() {
-        return sourceType;
-    }
-
-    public void setSourceType(SourceTypeEnum sourceType) {
-        this.sourceType = sourceType;
-    }
-
-    public ClientEnum getClientType() {
-        return clientType;
-    }
-
-    public void setClientType(ClientEnum clientType) {
-        this.clientType = clientType;
-    }
-
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-    
-	public Long getUserId() {
-        return userId;
-    }
-
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
-
-    public String getOrderNo() {
-        return orderNo;
-    }
-
-    public void setOrderNo(String orderNo) {
-        this.orderNo = orderNo;
-    }
-
-    public String getSubOrderNo() {
-        return subOrderNo;
-    }
-
-    public void setSubOrderNo(String subOrderNo) {
-        this.subOrderNo = subOrderNo;
-    }
-
-    public Long getVipCardId() {
-        return vipCardId;
-    }
-
-    public void setVipCardId(Long vipCardId) {
-        this.vipCardId = vipCardId;
-    }
-
-    public Date getStartTime() {
-        return startTime;
-    }
-
-    public void setStartTime(Date startTime) {
-        this.startTime = startTime;
-    }
-    
-	public Date getCreateTime() {
-        return createTime;
-    }
-
-    public void setCreateTime(Date createTime) {
-        this.createTime = createTime;
-    }
-    
-	public Date getUpdateTime() {
-        return updateTime;
-    }
-
-    public void setUpdateTime(Date updateTime) {
-        this.updateTime = updateTime;
-    }
-    
-	public Date getEndTime() {
-        return endTime;
-    }
-
-    public void setEndTime(Date endTime) {
-        this.endTime = endTime;
-    }
-
-    public Integer getMsgStatus() {
-        return msgStatus;
-    }
-
-    public void setMsgStatus(Integer msgStatus) {
-        this.msgStatus = msgStatus;
-    }
+    @ApiModelProperty("会员类型 VIP,SVIP")
+    @TableField(value = "vip_type_")
+    private EVipType vipType;
+
+    @ApiModelProperty("状态 ADD:新增,DEDUCTION:扣减,UPDATE:变更")
+    @TableField(value = "status_")
+    private EVipRecordStatus status;
+
+    @ApiModelProperty("是否展示1:展示,0:隐藏")
+    @TableField(value = "display_flag_")
+    private Boolean displayFlag;
+
+    @ApiModelProperty("是否有效 1:有效,0:失效")
+    @TableField(value = "efficient_flag_")
+    private Boolean efficientFlag;
+
+    @ApiModelProperty("关联ID")
+    @TableField(value = "ref_id_")
+    private Long refId;
+
+    @ApiModelProperty("是否发送消息")
+    @TableField(value = "send_msg_")
+    private Boolean sendMsg;
+
 }
 }

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

@@ -16,6 +16,7 @@ public enum AccountBizTypeEnum implements BaseEnum<String, AccountBizTypeEnum> {
     VIDEO("视频课"),
     VIDEO("视频课"),
     MUSIC("乐谱购买"),
     MUSIC("乐谱购买"),
     VIP("会员充值"),
     VIP("会员充值"),
+    SVIP("SVIP会员充值"),
     MALL("商品购买"),
     MALL("商品购买"),
     PIANO_ROOM("琴房充值"),
     PIANO_ROOM("琴房充值"),
     ACTI_REGIST("活动报名"),
     ACTI_REGIST("活动报名"),

+ 33 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EUserVipType.java

@@ -0,0 +1,33 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 用户会员类型
+ */
+public enum EUserVipType implements BaseEnum<String, EUserVipType> {
+
+    NORMAL("普通用户"),
+    VIP("VIP会员"),
+    SVIP("SVIP会员"),
+
+    ;
+    @EnumValue
+    private String code;
+    private String name;
+
+    EUserVipType(String name) {
+        this.code = this.name();
+        this.name = name;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 37 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EVipRecordStatus.java

@@ -0,0 +1,37 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 认证审核类型 ADD 新增 MODIFY 修改
+ *
+ * @Author: liweifan
+ * @Data: 2022/3/16 10:19
+ */
+public enum EVipRecordStatus implements BaseEnum<String, EVipRecordStatus> {
+
+    //状态 ADD:新增,DEDUCTION:扣减,UPDATE:变更
+    ADD("新增"),
+    DEDUCTION("扣减"),
+    UPDATE("变更"),
+
+    ;
+    @EnumValue
+    private String code;
+    private String name;
+
+    EVipRecordStatus(String name) {
+        this.code = this.name();
+        this.name = name;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

+ 46 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/EVipType.java

@@ -0,0 +1,46 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 认证审核类型 ADD 新增 MODIFY 修改
+ *
+ * @Author: liweifan
+ * @Data: 2022/3/16 10:19
+ */
+public enum EVipType implements BaseEnum<String, EVipType> {
+
+    // 字段 说明 VIP:会员 SVIP:SVIP,PERMANENT_SVIP:永久SVIP,NOT_VIP:不是vip
+
+    VIP("VIP"),
+    SVIP("SVIP"),
+
+
+    // 业务用字段
+    // 永久SVIP
+    PERMANENT_SVIP("永久SVIP"),
+
+    // 不是vip
+    NOT_VIP("不是vip"),
+    ALL_VIP("所有VIP"),
+
+    ;
+    @EnumValue
+    private String code;
+    private String name;
+
+    EVipType(String name) {
+        this.code = this.name();
+        this.name = name;
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getName() {
+        return name;
+    }
+}

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

@@ -11,6 +11,7 @@ import com.yonge.toolset.base.enums.BaseEnum;
  */
  */
 public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
 public enum GoodTypeEnum implements BaseEnum<String, GoodTypeEnum> {
     VIP("开通会员"),
     VIP("开通会员"),
+    SVIP("开通会员 SVIP"),
     PRACTICE("陪练课购买"),
     PRACTICE("陪练课购买"),
     LIVE("直播课购买"),
     LIVE("直播课购买"),
     VIDEO("视频课购买"),
     VIDEO("视频课购买"),

+ 24 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MessageTypeEnum.java

@@ -62,14 +62,22 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     STUDENT_JOIN_FANSGROUP("学员申请加入粉丝群"),
     STUDENT_JOIN_FANSGROUP("学员申请加入粉丝群"),
     STUDENT_AUTOJOIN_FANSGROUP("学员自动加入粉丝群"),
     STUDENT_AUTOJOIN_FANSGROUP("学员自动加入粉丝群"),
 
 
-    VIP_BUY_SUCCESS("会员购买成功"),
-    SMS_VIP_BUY_SUCCESS("会员购买成功(短信)"),
-
-    VIP_EXPIRE_THIRTY_DAY("会员到期前30天"),
-    SMS_VIP_EXPIRE_THIRTY_DAY("会员到期前30天(短信)"),
-
-    VIP_EXPIRE("会员到期"),
-    SMS_VIP_EXPIRE("会员到期(短信)"),
+//    VIP_BUY_SUCCESS("会员购买成功"),
+    NEW_VIP_BUY_SUCCESS("会员购买成功"),
+    NEW_TEACHER_VIP_BUY_SUCCESS("会员购买成功"),
+//    SMS_VIP_BUY_SUCCESS("会员购买成功(短信)"),
+    SMS_NEW_VIP_BUY_SUCCESS("会员购买成功(短信)"),
+    SMS_TEACHER_NEW_VIP_BUY_SUCCESS("会员购买成功(短信)"),
+
+    VIP_EXPIRE_THIRTY_DAY("VIP会员到期前30天"),
+    SVIP_EXPIRE_THIRTY_DAY("SVIP会员到期前30天"),
+    SMS_VIP_EXPIRE_THIRTY_DAY("VIP会员到期前30天(短信)"),
+    SMS_SVIP_EXPIRE_THIRTY_DAY("SVIP会员到期前30天(短信)"),
+
+    VIP_EXPIRE("VIP会员到期"),
+    SVIP_EXPIRE("SVIP会员到期"),
+    SMS_VIP_EXPIRE("VIP会员到期(短信)"),
+    SMS_SVIP_EXPIRE("SVIP会员到期(短信)"),
 
 
     PRACTICE_BUY("陪练课购买"),
     PRACTICE_BUY("陪练课购买"),
     SMS_PRACTICE_BUY("陪练课购买(短信)"),
     SMS_PRACTICE_BUY("陪练课购买(短信)"),
@@ -110,6 +118,14 @@ public enum MessageTypeEnum implements BaseEnum<String, MessageTypeEnum> {
     PRACTICE_ADJUST("陪练课调整"),
     PRACTICE_ADJUST("陪练课调整"),
     ACTIVITY_WIN("获奖消息"),
     ACTIVITY_WIN("获奖消息"),
     PLATFORM_ADD_VIP("会员赠送"),
     PLATFORM_ADD_VIP("会员赠送"),
+    PLATFORM_ADD_SVIP("会员赠送"),
+
+    PLATFORM_ADD_PER_SVIP("会员永久赠送"),
+
+    PLATFORM_ADD_DUDECT_VIP("会员扣减"),
+    PLATFORM_ADD_DUDECT_SVIP("会员扣减"),
+    PLATFORM_ADD_DUDECT_PER_SVIP("会员永久扣减"),
+
     SMS_STUDENT_LIVE_COMPLETION_FAIL("直播课成课失败"),
     SMS_STUDENT_LIVE_COMPLETION_FAIL("直播课成课失败"),
     STUDENT_LIVE_COMPLETION_FAIL("直播课成课失败"),
     STUDENT_LIVE_COMPLETION_FAIL("直播课成课失败"),
     COUPON_ISSUE("优惠券发放"),
     COUPON_ISSUE("优惠券发放"),

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

@@ -11,6 +11,7 @@ import com.yonge.toolset.base.enums.BaseEnum;
  */
  */
 public enum OrderTypeEnum implements BaseEnum<String, OrderTypeEnum> {
 public enum OrderTypeEnum implements BaseEnum<String, OrderTypeEnum> {
     VIP("开通会员"),
     VIP("开通会员"),
+    SVIP("开通会员 SVIP"),
     PRACTICE("陪练课购买"),
     PRACTICE("陪练课购买"),
     LIVE("直播课购买"),
     LIVE("直播课购买"),
     VIDEO("视频课购买"),
     VIDEO("视频课购买"),

+ 4 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/PeriodEnum.java

@@ -12,7 +12,10 @@ public enum PeriodEnum implements BaseEnum<String, PeriodEnum> {
 	MONTH("月"),
 	MONTH("月"),
 	QUARTERLY("季度"),
 	QUARTERLY("季度"),
 	YEAR_HALF("半年"),
 	YEAR_HALF("半年"),
-	YEAR("年");
+	YEAR("年"),
+	PERPETUAL("永久"),
+
+    ;
 
 
 	@EnumValue
 	@EnumValue
 	private String code;
 	private String code;

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

@@ -16,9 +16,11 @@ public enum SourceTypeEnum implements BaseEnum<String, AuditStatusEnum> {
     // 机构,机构自己上传曲目 , 暂时没有
     // 机构,机构自己上传曲目 , 暂时没有
     TENANT("机构"),
     TENANT("机构"),
     PLATFORM("平台"),
     PLATFORM("平台"),
+    PLATFORM_DEDUCT("后台扣减"),
     ACTIVITY("活动"),
     ACTIVITY("活动"),
     ORDER("订单"),
     ORDER("订单"),
     BACKEND_GIVE("后台赠送"),
     BACKEND_GIVE("后台赠送"),
+    FREE_UPGRADE("免费升级"),
 
 
 
 
     ;
     ;

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

@@ -16,6 +16,7 @@ public enum CouponCategoryEnum implements BaseEnum<String, CouponCategoryEnum> {
 
 
     UNIVERSAL("全场通用", "UNIVERSAL"),
     UNIVERSAL("全场通用", "UNIVERSAL"),
     VIP("小酷Ai", "VIP"),
     VIP("小酷Ai", "VIP"),
+    SVIP("小酷Ai SVIP ", "SVIP"),
     PIANO("云酷琴房", "PIANO_ROOM"),
     PIANO("云酷琴房", "PIANO_ROOM"),
     MALL("商场购物券", "MALL"),
     MALL("商场购物券", "MALL"),
     MUSIC("单曲点播券", "MUSIC"),
     MUSIC("单曲点播券", "MUSIC"),

+ 21 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseScheduleService.java

@@ -10,11 +10,21 @@ import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
 import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
-import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
-import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.vo.ArrangeCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseAdjustVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoClassVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomePage;
+import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
-import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.PageInfo;
@@ -247,7 +257,14 @@ public interface CourseScheduleService extends IService<CourseSchedule> {
 
 
     PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param);
     PageInfo<CourseStudentVo> selectStudent(Map<String, Object> param);
 
 
-    void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
+    String arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
+
+    /**
+     * 校验排课
+     * @param arrangeCourseVo 排课参数
+     * @param teacherId 老师id
+     */
+    String checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId);
 
 
     Map<String, Object> selectConsumeTime(String month, Long teacherId);
     Map<String, Object> selectConsumeTime(String month, Long teacherId);
 
 

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

@@ -92,5 +92,12 @@ public interface ImGroupMemberService extends IService<ImGroupMember> {
     List<ImGroupMember> findChatGroupAllMemberInfo(Map<String, Object> params);
     List<ImGroupMember> findChatGroupAllMemberInfo(Map<String, Object> params);
 
 
     IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(@Param("page") IPage<ImGroupMemberWrapper.ImGroupMember> page,@Param("query") ImGroupMemberWrapper.ImGroupMemberQuery query);
     IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(@Param("page") IPage<ImGroupMemberWrapper.ImGroupMember> page,@Param("query") ImGroupMemberWrapper.ImGroupMemberQuery query);
+
+    /**
+     * 获取群成员数量
+     * @param groupId 群ID
+     * @return int
+     */
+    int countGroupMember(String groupId);
 }
 }
 
 

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

@@ -85,10 +85,11 @@ public interface ImGroupService extends IService<ImGroup> {
     * @description: 成课后自动创建群聊,建议放在最后执行
     * @description: 成课后自动创建群聊,建议放在最后执行
      * @param courseGroupId 课程组编号
      * @param courseGroupId 课程组编号
      * @param courseGroupType 课程组类型
      * @param courseGroupType 课程组类型
+     * @param noGroupJoinUserIds 未加入群聊的用户编号
     * @author zx
     * @author zx
     * @date 2022/3/22 11:17
     * @date 2022/3/22 11:17
     */
     */
-    String autoCreate(Long courseGroupId,String courseGroupType) throws Exception;
+    String autoCreate(Long courseGroupId,String courseGroupType, List<Long> noGroupJoinUserIds) throws Exception;
 
 
     List<GroupMemberWrapper.ImGroupMember> getImGroupMembers(List<ImGroupMember> groupMemberList);
     List<GroupMemberWrapper.ImGroupMember> getImGroupMembers(List<ImGroupMember> groupMemberList);
 
 
@@ -144,6 +145,13 @@ public interface ImGroupService extends IService<ImGroup> {
      */
      */
     ImGroup findGroupInfoById(String groupId, Long userId);
     ImGroup findGroupInfoById(String groupId, Long userId);
 
 
+    /**
+     * 获取群信息
+     * @param groupId 群ID
+     * @return ImGroup
+     */
+    ImGroup getGroupById(String groupId);
+
     void getAndSaveImHistoryMessage(String date) throws Exception;
     void getAndSaveImHistoryMessage(String date) throws Exception;
 
 
     /**
     /**

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

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
 import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
@@ -41,7 +42,7 @@ public interface ImUserFriendService extends IService<ImUserFriend> {
     * @author zx
     * @author zx
     * @date 2022/3/24 12:03
     * @date 2022/3/24 12:03
     */
     */
-    ImUserFriend getDetail(String userId, ClientEnum clientType);
+    ImUserFriendVO.ImUserFriend getDetail(String userId, ClientEnum clientType);
 
 
     /**
     /**
      * 新用户自动添加客服
      * 新用户自动添加客服
@@ -52,6 +53,8 @@ public interface ImUserFriendService extends IService<ImUserFriend> {
      */
      */
     Integer registerUserBindCustomerService(Long userId, List<Long> friendIds, ClientEnum clientType);
     Integer registerUserBindCustomerService(Long userId, List<Long> friendIds, ClientEnum clientType);
 
 
+    void sendCustomerServiceAddFriendMessage(Long customerServiceId, String sendTitle, String sendMessage, List<Long> friendIds, ClientEnum friendType);
+
     /**
     /**
      * 发送系统客服消息
      * 发送系统客服消息
      * @param sender 发送者
      * @param sender 发送者

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

@@ -87,7 +87,7 @@ public interface MemberPriceSettingsService extends IService<MemberPriceSettings
      * @param sysUser
      * @param sysUser
      * @return
      * @return
      */
      */
-    Boolean addVip(VipSubmitReq vipSubmitReq, ClientEnum client, SysUser sysUser);
+//    Boolean addVip(VipSubmitReq vipSubmitReq, ClientEnum client, SysUser sysUser);
 
 
     /**
     /**
      * 会员信息
      * 会员信息

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

@@ -10,6 +10,7 @@ import com.yonge.cooleshow.biz.dal.dto.ReasonDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.*;
 import com.yonge.cooleshow.biz.dal.dto.search.*;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheetAccompaniment;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
@@ -46,7 +47,7 @@ public interface MusicSheetService extends IService<MusicSheet> {
 
 
     IPage<MusicSheetVoResult> selectCbsPage(IPage<MusicSheetVo> page, MusicSheetSearch query);
     IPage<MusicSheetVoResult> selectCbsPage(IPage<MusicSheetVo> page, MusicSheetSearch query);
     
     
-    IPage<MusicSheetVo> queryRelatedList(IPage<MusicSheetVo> page, Long albumId, Long musicSheetId);
+    IPage<MusicSheetVo> queryRelatedList(IPage<MusicSheetVo> page, MusicSheetRelatedQueryInfo queryInfo);
 
 
     /**
     /**
      * 曲目状态修改 启用、停用
      * 曲目状态修改 启用、停用
@@ -415,4 +416,6 @@ public interface MusicSheetService extends IService<MusicSheet> {
     PageInfo<CbsMusicSheetWrapper.MusicSheetAccApplication> queryCbsMusicSheetSoundApplication(CbsMusicSheetWrapper.MusicSheetApplicationQuery query);
     PageInfo<CbsMusicSheetWrapper.MusicSheetAccApplication> queryCbsMusicSheetSoundApplication(CbsMusicSheetWrapper.MusicSheetApplicationQuery query);
 
 
     List<CbsMusicSheetWrapper.MusicSheetApplication> queryCbsMusicSheetApplication(CbsMusicSheetWrapper.MusicSheetApplicationQuery query);
     List<CbsMusicSheetWrapper.MusicSheetApplication> queryCbsMusicSheetApplication(CbsMusicSheetWrapper.MusicSheetApplicationQuery query);
+
+    IPage<MusicSheetVo> queryTenantRelatedList(IPage<Object> page, MusicSheetRelatedQueryInfo queryInfo);
 }
 }

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

@@ -133,4 +133,5 @@ public interface StudentService extends IService<Student> {
     void sendStudentTenantChange(Student student, Long toTenantId);
     void sendStudentTenantChange(Student student, Long toTenantId);
 
 
     Map<Long,Student> getMapByIds(List<Long> userIds);
     Map<Long,Student> getMapByIds(List<Long> userIds);
+
 }
 }

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

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.service;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
 import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
 import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
 import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
@@ -186,4 +187,8 @@ public interface TeacherService extends IService<Teacher> {
     UserPaymentOrderWrapper.AccountTenantTo teacherSettlementFrom(Long teacherId,Long recomUserId);
     UserPaymentOrderWrapper.AccountTenantTo teacherSettlementFrom(Long teacherId,Long recomUserId);
 
 
     Map<Long, Teacher> getMapByIds(List<Long> teacherIds);
     Map<Long, Teacher> getMapByIds(List<Long> teacherIds);
+
+    List<Teacher> getCustomerService();
+
+    void updateLock(SysUser sysUser, Long teacherId);
 }
 }

+ 41 - 5
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/VipCardRecordService.java

@@ -2,22 +2,22 @@ package com.yonge.cooleshow.biz.dal.service;
 
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.IService;
-import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
-import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.VipRecordVo;
-import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
-import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.PageInfo;
 
 
+import java.util.List;
+import java.util.Map;
+
 /**
 /**
  * 购买会员卡记录表 服务类
  * 购买会员卡记录表 服务类
  *
  *
@@ -83,4 +83,40 @@ public interface VipCardRecordService extends IService<VipCardRecord> {
      * @return
      * @return
      */
      */
     PageInfo<VipRecordVo> vipRecord(VipRecordSearch recordSearch);
     PageInfo<VipRecordVo> vipRecord(VipRecordSearch recordSearch);
+
+    /**
+     * 获取生效中的会员记录
+     *
+     * @param userId
+     * @param clientEnum
+     * @return
+     */
+    List<VipCardRecord> getEfficientVipRecord(List<Long> userId, ClientEnum clientEnum);
+
+    VipCardRecordWrapper.UserVip UserVipInfo(Long userId, ClientEnum clientEnum);
+
+    /**
+     * 用户会员信息
+     *
+     * @param userId
+     * @param clientEnum
+     * @return
+     */
+    VipCardRecordWrapper.UserVip userVipInfo(Long userId, ClientEnum clientEnum);
+
+    void add(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord);
+
+    /**
+     * 获取用户会员类型
+     *
+     * @param studentIds
+     * @param client
+     * @return
+     */
+    Map<Long, EVipType> getVipTypeMapByUserIds(List<Long> studentIds, ClientEnum client);
+
+    // 会员添加
+    VipCardRecord addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord);
+
+    List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(List<Long> userIdList , String clientType);
 }
 }

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

@@ -48,6 +48,8 @@ public interface ImGroupCoreService {
     String analysisImUserId(String imUserId);
     String analysisImUserId(String imUserId);
 
 
 
 
+    String analysisImUser(String imUserId);
+
     /**
     /**
      * 检测imUserid
      * 检测imUserid
      *
      *

+ 12 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/im/impl/ImGroupCoreServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.dayaedu.cbs.common.enums.EClientType;
 import com.dayaedu.cbs.common.enums.EClientType;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
 import com.microsvc.toolkit.common.tools.ThreadPool;
 import com.microsvc.toolkit.common.tools.ThreadPool;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.ImPluginService;
 import com.microsvc.toolkit.middleware.im.ImPluginService;
@@ -19,7 +18,6 @@ import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
@@ -27,14 +25,12 @@ import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
-import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberAuditWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberAuditWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.CollectionUtils;
-import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -120,7 +116,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
             clientType = "TEACHER";
             clientType = "TEACHER";
         }
         }
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
-            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId, clientType);
+            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId.toString(), clientType);
         }
         }
         return imUserId;
         return imUserId;
     }
     }
@@ -133,7 +129,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
             clientType = "TEACHER";
             clientType = "TEACHER";
         }
         }
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
         if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && !imUserId.startsWith(imConfig.getAppPrefix())) {
-            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId, clientType);
+            imUserId = MessageFormat.format("{0}_{1}_{2}", imConfig.getAppPrefix(), userId.toString(), clientType);
         }
         }
         return imUserId;
         return imUserId;
     }
     }
@@ -152,6 +148,13 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
         }
         }
         return imUserId;
         return imUserId;
     }
     }
+    @Override
+    public String analysisImUser(String imUserId) {
+        if (StringUtils.isNotBlank(imConfig.getAppPrefix()) && imUserId.startsWith(imConfig.getAppPrefix())) {
+            return imUserId.replace(imConfig.getAppPrefix() + "_", "");
+        }
+        return imUserId;
+    }
 
 
 
 
     /**
     /**
@@ -738,7 +741,6 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
      */
      */
     @Override
     @Override
     public void changeGroupOwner(String groupId, String newOwner, String oldOwner) throws Exception {
     public void changeGroupOwner(String groupId, String newOwner, String oldOwner) throws Exception {
-
         try {
         try {
             if (newOwner.equals(oldOwner)) {
             if (newOwner.equals(oldOwner)) {
                 throw new BizException("不能转让给自己");
                 throw new BizException("不能转让给自己");
@@ -746,7 +748,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
 
 
             {
             {
                 // 判断旧群主
                 // 判断旧群主
-                String[] values = analysisImUserId(oldOwner).split(IM_USER_ID_SPLIT);
+                String[] values = analysisImUser(oldOwner).split(IM_USER_ID_SPLIT);
 
 
                 // 新群主ID和身份
                 // 新群主ID和身份
                 long userId = Long.parseLong(values[0]);
                 long userId = Long.parseLong(values[0]);
@@ -765,7 +767,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
 
 
             {
             {
                 // 判定新群主是否为禁言状态,需要先解除禁言
                 // 判定新群主是否为禁言状态,需要先解除禁言
-                String[] values = analysisImUserId(newOwner).split(IM_USER_ID_SPLIT);
+                String[] values = analysisImUser(newOwner).split(IM_USER_ID_SPLIT);
 
 
                 // 新群主ID和身份
                 // 新群主ID和身份
                 long userId = Long.parseLong(values[0]);
                 long userId = Long.parseLong(values[0]);
@@ -1016,7 +1018,7 @@ public class ImGroupCoreServiceImpl implements ImGroupCoreService {
      * @param isAdmin 群主标记
      * @param isAdmin 群主标记
      */
      */
     private void updateGroupOwner(String groupId, String groupMember, Boolean isAdmin) {
     private void updateGroupOwner(String groupId, String groupMember, Boolean isAdmin) {
-        String[] values = analysisImUserId(groupMember).split(IM_USER_ID_SPLIT);
+        String[] values = analysisImUser(groupMember).split(IM_USER_ID_SPLIT);
 
 
         // 新群主ID和身份
         // 新群主ID和身份
         long userId = Long.parseLong(values[0]);
         long userId = Long.parseLong(values[0]);

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

@@ -317,7 +317,7 @@ public class ActivityRewardServiceImpl extends ServiceImpl<ActivityRewardDao, Ac
             pianoRoomChangeRecord.setCreateTime(new Date());
             pianoRoomChangeRecord.setCreateTime(new Date());
             pianoRoomChangeRecord.setReason(activityPlan.getActivityName());
             pianoRoomChangeRecord.setReason(activityPlan.getActivityName());
             pianoRoomChangeRecordService.add(pianoRoomChangeRecord);
             pianoRoomChangeRecordService.add(pianoRoomChangeRecord);
-        } else if (activityReward.getRewardType().equals(RewardTypeEnum.VIP)) {
+        } else if (activityReward.getRewardType().equals(RewardTypeEnum.VIP) || activityReward.getRewardType().equals(RewardTypeEnum.SVIP)) {
             // VIP
             // VIP
             memberPriceSettingsService.activityReward(userId, activityPlan.getActivityClient(), activityReward,
             memberPriceSettingsService.activityReward(userId, activityPlan.getActivityClient(), activityReward,
                                                       activityPlan.getId(), activityPlan.getActivityName());
                                                       activityPlan.getId(), activityPlan.getActivityName());

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

@@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.beust.jcommander.internal.Lists;
+import com.google.common.collect.Lists;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -1250,9 +1250,15 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                 if (courseGroup.getPreStudentNum() >= courseGroup.getMixStudentNum() &&courseGroup.getStatus().equals(CourseGroupEnum.APPLY.getCode())) {
                 if (courseGroup.getPreStudentNum() >= courseGroup.getMixStudentNum() &&courseGroup.getStatus().equals(CourseGroupEnum.APPLY.getCode())) {
                     //人数达标则修改课程组为进行中状态
                     //人数达标则修改课程组为进行中状态
                     courseGroup.setStatus(CourseGroupEnum.ING.getCode());
                     courseGroup.setStatus(CourseGroupEnum.ING.getCode());
+                    List<Long> noGroupJoinUserIds = Lists.newArrayList();
                     //创建群聊 并添加人员到群中
                     //创建群聊 并添加人员到群中
-                    String imGroupId = imGroupService.autoCreate(courseGroup.getId(), courseGroup.getType());
+                    String imGroupId = imGroupService.autoCreate(courseGroup.getId(), courseGroup.getType(), noGroupJoinUserIds);
 
 
+                    // 排除未进群的学生
+                    if (CollectionUtils.isNotEmpty(noGroupJoinUserIds)) {
+                        noGroupJoinUserIds.forEach(userIds::remove);
+                    }
+                    // 更新已进群用户身份
                     imGroupMemberService.initGroupMembers(imGroupId, userIds, ImGroupMemberRoleType.STUDENT);
                     imGroupMemberService.initGroupMembers(imGroupId, userIds, ImGroupMemberRoleType.STUDENT);
                     //添加老师进群
                     //添加老师进群
                     imGroupMemberService.initGroupMembers(imGroupId, Collections.singleton(courseGroup.getTeacherId()), ImGroupMemberRoleType.TEACHER);
                     imGroupMemberService.initGroupMembers(imGroupId, Collections.singleton(courseGroup.getTeacherId()), ImGroupMemberRoleType.TEACHER);

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

@@ -10,9 +10,11 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.*;
 import com.yonge.cooleshow.biz.dal.dao.*;
+import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
@@ -54,7 +56,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.math.RoundingMode;
-import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.text.SimpleDateFormat;
 import java.time.Instant;
 import java.time.Instant;
 import java.time.LocalDate;
 import java.time.LocalDate;
@@ -1954,16 +1955,23 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
      * @Author: cy
      * @Author: cy
      * @Date: 2022/5/27
      * @Date: 2022/5/27
      */
      */
-    public void arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
-        DistributedLock.of(redissonClient)
-                .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
-                        , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
+    public String arrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+
+        // 返回未加入群用户消息
+        return DistributedLock.of(redissonClient)
+            .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey("teacherId:" + teacherId)
+                , () -> this.checkArrangeCourse(arrangeCourseVo, teacherId), 60L, TimeUnit.SECONDS);
     }
     }
 
 
+    /**
+     * 校验排课
+     * @param arrangeCourseVo 排课参数
+     * @param teacherId 老师id
+     */
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
-    public void checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
+    public String checkArrangeCourse(ArrangeCourseVo arrangeCourseVo, Long teacherId) {
         Integer classNum = arrangeCourseVo.getClassNum();//课时数
         Integer classNum = arrangeCourseVo.getClassNum();//课时数
-        Integer singleClssTime = arrangeCourseVo.getSingleClssTime();//单课时长
+        Integer singleClassTime = arrangeCourseVo.getSingleClssTime();//单课时长
         List<Long> studentIds = arrangeCourseVo.getStudentIds();//学员id集合
         List<Long> studentIds = arrangeCourseVo.getStudentIds();//学员id集合
 
 
         String formula = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_TIME_FORMULA);
         String formula = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_TIME_FORMULA);
@@ -1971,13 +1979,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         if (n == null) {
         if (n == null) {
             throw new BizException("公式转换失败");
             throw new BizException("公式转换失败");
         }
         }
-        Integer consumTime = classNum * singleClssTime * n;//消耗时长 课程数*单课时长*人数
+        Integer consumTime = classNum * singleClassTime * n;//消耗时长 课程数*单课时长*人数
 
 
         List<CourseTimeEntity> timeList = arrangeCourseVo.getTimeList();//选课时间
         List<CourseTimeEntity> timeList = arrangeCourseVo.getTimeList();//选课时间
         Integer consumeTime = arrangeCourseVo.getConsumeTime();
         Integer consumeTime = arrangeCourseVo.getConsumeTime();
 
 
         log.info("classNum:" + classNum);
         log.info("classNum:" + classNum);
-        log.info("singleClssTime:" + singleClssTime);
+        log.info("singleClssTime:" + singleClassTime);
         log.info("n:" + n);
         log.info("n:" + n);
         log.info("消耗时长:" + consumTime);
         log.info("消耗时长:" + consumTime);
         log.info("传入时长:" + consumeTime);
         log.info("传入时长:" + consumeTime);
@@ -2002,7 +2010,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             if (timeList.get(i).getStartTime().before(new Date())) {
             if (timeList.get(i).getStartTime().before(new Date())) {
                 throw new BizException("上课时间必须大于当前时间");
                 throw new BizException("上课时间必须大于当前时间");
             }
             }
-            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClssTime).equals(timeList.get(i).getEndTime())) {
+            if (!DateUtil.offsetMinute(timeList.get(i).getStartTime(), singleClassTime).equals(timeList.get(i).getEndTime())) {
                 throw new BizException("第{}节课结束时间计算错误", i + 1);
                 throw new BizException("第{}节课结束时间计算错误", i + 1);
             }
             }
         }
         }
@@ -2059,7 +2067,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         courseGroup.setTeacherId(teacherId);
         courseGroup.setTeacherId(teacherId);
         courseGroup.setName(arrangeCourseVo.getCourseName());
         courseGroup.setName(arrangeCourseVo.getCourseName());
         courseGroup.setSubjectId(arrangeCourseVo.getSubjectId());
         courseGroup.setSubjectId(arrangeCourseVo.getSubjectId());
-        courseGroup.setSingleCourseMinutes(singleClssTime);
+        courseGroup.setSingleCourseMinutes(singleClassTime);
         courseGroup.setCourseNum(classNum);
         courseGroup.setCourseNum(classNum);
         courseGroup.setStatus(CourseGroupEnum.ING.getCode());
         courseGroup.setStatus(CourseGroupEnum.ING.getCode());
         courseGroup.setCreatedBy(teacherId);
         courseGroup.setCreatedBy(teacherId);
@@ -2079,7 +2087,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             schedule.setLock(0);
             schedule.setLock(0);
             schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
             schedule.setStatus(CourseScheduleEnum.NOT_START.getCode());
             schedule.setCreatedBy(teacherId);
             schedule.setCreatedBy(teacherId);
-            schedule.setSingleCourseTime(singleClssTime);
+            schedule.setSingleCourseTime(singleClassTime);
             baseMapper.insert(schedule);
             baseMapper.insert(schedule);
 
 
             //添加payment
             //添加payment
@@ -2113,14 +2121,14 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                             roomTimeLock.setFrozenTime(frozenTimeLock + consumTime);
                             roomTimeLock.setFrozenTime(frozenTimeLock + consumTime);
                             pianoRoomTimeDao.update(roomTimeLock, Wrappers.<PianoRoomTime>lambdaQuery().eq(PianoRoomTime::getTeacherId, teacherId));
                             pianoRoomTimeDao.update(roomTimeLock, Wrappers.<PianoRoomTime>lambdaQuery().eq(PianoRoomTime::getTeacherId, teacherId));
                             return null;
                             return null;
-                        }, null, 10l);
+                        }, null, 10L);
 
 
+        List<Long> noGroupJoinUserIds = Lists.newArrayList();
         //创建群聊
         //创建群聊
         try {
         try {
-            imGroupService.autoCreate(courseGroup.getId(), CourseScheduleEnum.PIANO_ROOM_CLASS.getCode());
+            imGroupService.autoCreate(courseGroup.getId(), CourseScheduleEnum.PIANO_ROOM_CLASS.getCode(), noGroupJoinUserIds);
         } catch (Exception e) {
         } catch (Exception e) {
-            log.error("琴房课程组id:{},创建群聊失败:{}", courseGroup.getId(), e);
-            e.printStackTrace();
+            log.error("琴房课程组id:{},创建群聊失败", courseGroup.getId(), e);
         }
         }
 
 
         for (Long studentId : studentIds) {
         for (Long studentId : studentIds) {
@@ -2131,6 +2139,13 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
         }
         }
         //清除老师缓存
         //清除老师缓存
         redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(teacherId)).delete();
         redissonClient.getBucket(CacheNameEnum.TEACHER_TOTAL.getRedisKey(teacherId)).delete();
+
+        String message = "";
+        if (CollectionUtils.isNotEmpty(noGroupJoinUserIds)) {
+            // 返回未加入群用户消息
+            message = "群成员人数达到上限,有" + noGroupJoinUserIds.size() + "位学生未进入课程群";
+        }
+        return message;
     }
     }
 
 
     /**
     /**
@@ -2450,7 +2465,7 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
                                     .set(PianoRoomTime::getRemainTime, remainTime - diffTime)
                                     .set(PianoRoomTime::getRemainTime, remainTime - diffTime)
                                     .set(PianoRoomTime::getFrozenTime, frozenTime + diffTime));
                                     .set(PianoRoomTime::getFrozenTime, frozenTime + diffTime));
                             return null;
                             return null;
-                        }, null, 10l);
+                        }, null, 10L);
 
 
         //删除原学员
         //删除原学员
         paymentDao.delete(Wrappers.<CourseScheduleStudentPayment>lambdaQuery().eq(CourseScheduleStudentPayment::getCourseId, courseId));
         paymentDao.delete(Wrappers.<CourseScheduleStudentPayment>lambdaQuery().eq(CourseScheduleStudentPayment::getCourseId, courseId));

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

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -211,7 +212,14 @@ public class CustomerServiceBatchSendingServiceImpl extends ServiceImpl<Customer
         // 发送客服ID
         // 发送客服ID
         String customerService = info.getMobile();
         String customerService = info.getMobile();
         if (StringUtils.isBlank(customerService)) {
         if (StringUtils.isBlank(customerService)) {
-            customerService = customerServiceConfig.getCustomerService();
+            List<Long> teacherIds = teacherService.getCustomerService().stream().map(Teacher::getUserId).collect(Collectors.toList());
+            if (!teacherIds.isEmpty()) {
+                customerService = sysUserMapper.selectList(new QueryWrapper<SysUser>().lambda()
+                                .in(SysUser::getId, teacherIds))
+                        .stream()
+                        .map(SysUser::getPhone)
+                        .collect(Collectors.joining(","));
+            }
         }
         }
         if (StringUtils.isNotEmpty(customerService)) {
         if (StringUtils.isNotEmpty(customerService)) {
 
 

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

@@ -141,6 +141,7 @@ public class HomeServiceImpl implements HomeService {
         List<HomeTotalStudent> totalList = baserMapper.totalStudent(query.getTimeType().getCode(), query);
         List<HomeTotalStudent> totalList = baserMapper.totalStudent(query.getTimeType().getCode(), query);
         Integer registerNum = 0;
         Integer registerNum = 0;
         Integer vipNum = 0;
         Integer vipNum = 0;
+        Integer svipNum = 0;
         Integer practiceNum = 0;
         Integer practiceNum = 0;
         Integer videoNum = 0;
         Integer videoNum = 0;
         Integer liveNum = 0;
         Integer liveNum = 0;
@@ -151,6 +152,7 @@ public class HomeServiceImpl implements HomeService {
         for (HomeTotalStudent totalStudent : totalList) {
         for (HomeTotalStudent totalStudent : totalList) {
             totalStudent.setRegisterNum(null == totalStudent.getRegisterNum() ? 0 : totalStudent.getRegisterNum());
             totalStudent.setRegisterNum(null == totalStudent.getRegisterNum() ? 0 : totalStudent.getRegisterNum());
             totalStudent.setVipNum(null == totalStudent.getVipNum() ? 0 : totalStudent.getVipNum());
             totalStudent.setVipNum(null == totalStudent.getVipNum() ? 0 : totalStudent.getVipNum());
+            totalStudent.setSvipNum(null == totalStudent.getSvipNum() ? 0 : totalStudent.getSvipNum());
             totalStudent.setPracticeNum(null == totalStudent.getPracticeNum() ? 0 : totalStudent.getPracticeNum());
             totalStudent.setPracticeNum(null == totalStudent.getPracticeNum() ? 0 : totalStudent.getPracticeNum());
             totalStudent.setVideoNum(null == totalStudent.getVideoNum() ? 0 : totalStudent.getVideoNum());
             totalStudent.setVideoNum(null == totalStudent.getVideoNum() ? 0 : totalStudent.getVideoNum());
             totalStudent.setLiveNum(null == totalStudent.getLiveNum() ? 0 : totalStudent.getLiveNum());
             totalStudent.setLiveNum(null == totalStudent.getLiveNum() ? 0 : totalStudent.getLiveNum());
@@ -160,6 +162,7 @@ public class HomeServiceImpl implements HomeService {
 
 
             registerNum += totalStudent.getRegisterNum();
             registerNum += totalStudent.getRegisterNum();
             vipNum += totalStudent.getVipNum();
             vipNum += totalStudent.getVipNum();
+            svipNum += totalStudent.getSvipNum();
             practiceNum += totalStudent.getPracticeNum();
             practiceNum += totalStudent.getPracticeNum();
             videoNum += totalStudent.getVideoNum();
             videoNum += totalStudent.getVideoNum();
             liveNum += totalStudent.getLiveNum();
             liveNum += totalStudent.getLiveNum();
@@ -170,6 +173,7 @@ public class HomeServiceImpl implements HomeService {
         HomeTotalStudent total = new HomeTotalStudent();
         HomeTotalStudent total = new HomeTotalStudent();
         total.setRegisterNum(registerNum);
         total.setRegisterNum(registerNum);
         total.setVipNum(vipNum);
         total.setVipNum(vipNum);
+        total.setSvipNum(svipNum);
         total.setPracticeNum(practiceNum);
         total.setPracticeNum(practiceNum);
         total.setVideoNum(videoNum);
         total.setVideoNum(videoNum);
         total.setLiveNum(liveNum);
         total.setLiveNum(liveNum);

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

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.dao.ImGroupMemberAuditDao;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
@@ -14,19 +15,28 @@ import com.yonge.cooleshow.biz.dal.queryInfo.ImGroupMemberAuditQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.vo.AuditUserInfo;
 import com.yonge.cooleshow.biz.dal.vo.AuditUserInfo;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
-import io.rong.models.group.GroupMember;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.util.*;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 /**
 /**
@@ -35,11 +45,10 @@ import java.util.stream.Collectors;
  * @author zx
  * @author zx
  * @since 2022-03-22 17:18:51
  * @since 2022-03-22 17:18:51
  */
  */
+@Slf4j
 @Service("imGroupMemberAuditService")
 @Service("imGroupMemberAuditService")
 public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAuditDao, ImGroupMemberAudit> implements ImGroupMemberAuditService {
 public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAuditDao, ImGroupMemberAudit> implements ImGroupMemberAuditService {
 
 
-    private final static Logger log = LoggerFactory.getLogger(ImGroupMemberAuditServiceImpl.class);
-
     @Resource
     @Resource
     private ImGroupService imGroupService;
     private ImGroupService imGroupService;
     @Resource
     @Resource
@@ -49,6 +58,12 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
     @Resource
     @Resource
     private SysMessageServiceImpl sysMessageService;
     private SysMessageServiceImpl sysMessageService;
 
 
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
     @Override
     @Override
     public ImGroupMemberAuditDao getDao() {
     public ImGroupMemberAuditDao getDao() {
         return this.baseMapper;
         return this.baseMapper;
@@ -79,36 +94,55 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
         if(Objects.nonNull(baseMapper.findOne(auditParams))){
         if(Objects.nonNull(baseMapper.findOne(auditParams))){
             throw new BizException("您有待审核的申请,请勿重复提交");
             throw new BizException("您有待审核的申请,请勿重复提交");
         }
         }
-        Date date = new Date();
-        //是否自动通过审核
-        imGroupMemberAudit.setAuditStatus(imGroup.getAutoPassFlag() && autoJoin?AuditStatusEnum.OPEN:AuditStatusEnum.AUDITING);
-        imGroupMemberAudit.setUpdateTime(date);
-        imGroupMemberAudit.setCreateTime(date);
-        baseMapper.insert(imGroupMemberAudit);
-        if(imGroup.getAutoPassFlag() && Optional.ofNullable(autoJoin).orElse(false)){
-            //处理本地群成员
-            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroup.getId(),
-                    imGroupMemberAudit.getUserId(), false,
-                    imGroupMemberAudit.getRoleType());
-            //同步群成员数量
-            imGroupService.getDao().updateMemberNum(imGroup.getId());
-            //加入融云群
-            imGroupMemberService.join(groupMembers,groupId);
-        } else {
-            Map<Long,String> receivers = new HashMap<>(1);
-            // 群创建人
-            SysUser user = sysUserService.findUserById(imGroup.getCreateBy());
-            // 申请人
-            SysUser auditUser = sysUserService.findUserById(imGroupMemberAudit.getUserId());
-
-            receivers.put(user.getId(), user.getPhone());
+
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_apply_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+
+            // 统计群成员数量,大于等于群组最大人数时,不允许加入
+            if (!verifyGroupMemberJoinLimit(groupId, 1)) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
             try {
             try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_JOIN_FANSGROUP,
-                           receivers, null, 0, null, ClientEnum.TEACHER.getCode(), auditUser.getUsername(),imGroup.getName());
+                Date date = new Date();
+                //是否自动通过审核
+                imGroupMemberAudit.setAuditStatus(imGroup.getAutoPassFlag() && autoJoin?AuditStatusEnum.OPEN:AuditStatusEnum.AUDITING);
+                imGroupMemberAudit.setUpdateTime(date);
+                imGroupMemberAudit.setCreateTime(date);
+                baseMapper.insert(imGroupMemberAudit);
+                if(imGroup.getAutoPassFlag() && Optional.ofNullable(autoJoin).orElse(false)){
+                    //处理本地群成员
+                    List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroup.getId(),
+                        imGroupMemberAudit.getUserId(), false,
+                        imGroupMemberAudit.getRoleType());
+                    //同步群成员数量
+                    imGroupService.getDao().updateMemberNum(imGroup.getId());
+                    //加入融云群
+                    imGroupMemberService.join(groupMembers,groupId);
+                } else {
+                    Map<Long,String> receivers = new HashMap<>(1);
+                    // 群创建人
+                    SysUser user = sysUserService.findUserById(imGroup.getCreateBy());
+                    // 申请人
+                    SysUser auditUser = sysUserService.findUserById(imGroupMemberAudit.getUserId());
+
+                    receivers.put(user.getId(), user.getPhone());
+                    try {
+                        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.STUDENT_JOIN_FANSGROUP,
+                            receivers, null, 0, null, ClientEnum.TEACHER.getCode(), auditUser.getUsername(),imGroup.getName());
+                    } catch (Exception e) {
+                        log.warn("学生入群消息发送失败,{}",e.getMessage());
+                    }
+                }
             } catch (Exception e) {
             } catch (Exception e) {
-                log.warn("学生入群消息发送失败,{}",e.getMessage());
+                log.error("加入群组申请失败,{}", e.getMessage(), e);
+                throw new BizException("加入群组申请失败");
             }
             }
-        }
+            return true;
+        }, null, 10L);
+
     }
     }
 
 
     @Override
     @Override
@@ -117,18 +151,53 @@ public class ImGroupMemberAuditServiceImpl extends ServiceImpl<ImGroupMemberAudi
         Optional.of(auditStatus).filter(e->e != AuditStatusEnum.AUDITING).orElseThrow(()->new BizException("操作失败:审核状态异常"));
         Optional.of(auditStatus).filter(e->e != AuditStatusEnum.AUDITING).orElseThrow(()->new BizException("操作失败:审核状态异常"));
         ImGroup imGroup = Optional.ofNullable(imGroupService.getById(groupId)).orElseThrow(() ->new BizException("群组信息不存在"));
         ImGroup imGroup = Optional.ofNullable(imGroupService.getById(groupId)).orElseThrow(() ->new BizException("群组信息不存在"));
         Optional.of(sysUserService.getUserId()).filter(imGroup.getCreateBy()::equals).orElseThrow(()->new BizException("操作失败:您没有审核权限"));
         Optional.of(sysUserService.getUserId()).filter(imGroup.getCreateBy()::equals).orElseThrow(()->new BizException("操作失败:您没有审核权限"));
-        //修改审核状态
-        baseMapper.batchUpdateAuditStatus(auditIds,auditStatus.getCode());
-        if(auditStatus == AuditStatusEnum.OPEN){
-            List<ImGroupMemberAudit> imGroupMemberAudit = baseMapper.findByIds(auditIds);
-            Set<Long> userIds = imGroupMemberAudit.stream().map(ImGroupMemberAudit::getUserId).collect(Collectors.toSet());
-            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId,userIds, ImGroupMemberRoleType.STUDENT);
-            //同步群成员数量
-            imGroupService.getDao().updateMemberNum(imGroup.getId());
-            //加入融云群
-            imGroupMemberService.join(groupMembers,imGroup.getId());
-            sendMessage(auditIds);
+
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_audit_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+
+            // 校验群成员加入限制
+            String[] split = auditIds.split(",");
+            if (AuditStatusEnum.OPEN.equals(auditStatus) && !verifyGroupMemberJoinLimit(groupId, split.length)) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+            try {
+                //修改审核状态
+                baseMapper.batchUpdateAuditStatus(auditIds,auditStatus.getCode());
+                if(auditStatus == AuditStatusEnum.OPEN){
+                    List<ImGroupMemberAudit> imGroupMemberAudit = baseMapper.findByIds(auditIds);
+                    Set<Long> userIds = imGroupMemberAudit.stream().map(ImGroupMemberAudit::getUserId).collect(Collectors.toSet());
+                    List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId,userIds, ImGroupMemberRoleType.STUDENT);
+                    //同步群成员数量
+                    imGroupService.getDao().updateMemberNum(imGroup.getId());
+                    //加入融云群
+                    imGroupMemberService.join(groupMembers,imGroup.getId());
+                    sendMessage(auditIds);
+                }
+            } catch (Exception e) {
+                log.error("加入群组审核失败,{}", e.getMessage(), e);
+                throw new BizException("加入群组审核失败");
+            }
+            return true;
+        }, null, 10L);
+
+    }
+
+    /**
+     * 校验群成员加入限制
+     * @param groupId 群组ID
+     */
+    private Boolean verifyGroupMemberJoinLimit(String groupId, int addNum) {
+        // 统计群成员数量,大于等于群组最大人数时,不允许加入
+        int memberCount = imGroupMemberService.countGroupMember(groupId);
+        // 查询群成员人数限制
+        SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+        if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0
+            && (memberCount + addNum) > Integer.parseInt(config.getParamValue())) {
+            return false;
         }
         }
+        return true;
     }
     }
 
 
     /**
     /**

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

@@ -266,5 +266,19 @@ public class ImGroupMemberServiceImpl extends ServiceImpl<ImGroupMemberDao, ImGr
     public IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(IPage<ImGroupMemberWrapper.ImGroupMember> page, ImGroupMemberWrapper.ImGroupMemberQuery query) {
     public IPage<ImGroupMemberWrapper.ImGroupMember> selectPage(IPage<ImGroupMemberWrapper.ImGroupMember> page, ImGroupMemberWrapper.ImGroupMemberQuery query) {
         return page.setRecords(imGroupMemberDao.selectPage(page, query));
         return page.setRecords(imGroupMemberDao.selectPage(page, query));
     }
     }
+
+    /**
+     * 获取群成员数量
+     *
+     * @param groupId 群ID
+     * @return int
+     */
+    @Override
+    public int countGroupMember(String groupId) {
+        if (org.apache.commons.lang3.StringUtils.isEmpty(groupId)) {
+            return 0;
+        }
+        return lambdaQuery().eq(ImGroupMember::getGroupId, groupId).count();
+    }
 }
 }
 
 

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

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
 import com.microsvc.toolkit.middleware.common.http.ImageUtil;
 import com.microsvc.toolkit.middleware.common.http.ImageUtil;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.ImPluginContext;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
 import com.microsvc.toolkit.middleware.im.message.GroupMemberWrapper;
@@ -33,6 +34,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
 import com.yonge.cooleshow.biz.dal.enums.RoleEnum;
@@ -64,6 +66,7 @@ import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.UploadReturnBean;
 import com.yonge.cooleshow.common.entity.UploadReturnBean;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ThreadPool;
 import com.yonge.toolset.base.util.ThreadPool;
+import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.date.DateUtil;
 import io.rong.RongCloud;
 import io.rong.RongCloud;
 import io.rong.methods.message.history.History;
 import io.rong.methods.message.history.History;
@@ -304,6 +307,12 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     @Override
     @Override
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
     public String create(ImGroupWrapper.ImGroup imGroup) throws Exception {
     public String create(ImGroupWrapper.ImGroup imGroup) throws Exception {
+        // 群成员数量限制校验
+        SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+        if (config != null && Integer.parseInt(config.getParamValue()) < (imGroup.getStudentIdList().size() + 1)) {
+            throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+        }
+
         Date now = new Date();
         Date now = new Date();
         if (imGroup.getType() == null) {
         if (imGroup.getType() == null) {
             imGroup.setType(ImGroupType.FAN.getCode());
             imGroup.setType(ImGroupType.FAN.getCode());
@@ -359,31 +368,52 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
             throw new BizException("添加的群成员不能为空");
             throw new BizException("添加的群成员不能为空");
 
 
         }
         }
-        List<ImGroupMember> groupMemberList = imGroupMemberService.initGroupMembers(groupId,
-                studentIdList, ImGroupMemberRoleType.STUDENT);
-        imGroupMemberService.join(groupMemberList, groupId);
-
-        // 如果是机构群,学生自动添加老师好友
-        if (ImGroupType.ORG.equals(imGroup.getType())) {
-            List<ImGroupMember> teacherList = imGroupMemberService.lambdaQuery()
-                    .eq(ImGroupMember::getGroupId, groupId)
-                    .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
-                    .list();
-            teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList));
-        }
+        // 增加群成员校验锁,当群成员人数达到限制时,不允许再次加入
+        String lockName = "klx:group_member_add_lock:" + groupId;
+        DistributedLock.of(redissonClient).runIfLockToFunction(lockName, (x)-> {
+            // 群成员数量限制校验
+            int memberCount = imGroupMemberService.countGroupMember(groupId);
+            // 查询群成员人数限制
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0
+                && (memberCount + studentIdList.size()) > Integer.parseInt(config.getParamValue())) {
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
+            try {
+                List<ImGroupMember> groupMemberList = imGroupMemberService.initGroupMembers(groupId,
+                    studentIdList, ImGroupMemberRoleType.STUDENT);
+                imGroupMemberService.join(groupMemberList, groupId);
+
+                // 如果是机构群,学生自动添加老师好友
+                if (ImGroupType.ORG.equals(imGroup.getType())) {
+                    List<ImGroupMember> teacherList = imGroupMemberService.lambdaQuery()
+                        .eq(ImGroupMember::getGroupId, groupId)
+                        .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.TEACHER)
+                        .list();
+                    teacherList.forEach(teacher -> imUserFriendService.saveUserFriend(teacher.getUserId(), studentIdList));
+                }
+            } catch (Exception e) {
+                log.error("加入群组失败,{}", e.getMessage(), e);
+                throw new BizException(e.getMessage());
+            }
+            return true;
+        }, null, 10L);
+
     }
     }
 
 
 
 
     @Override
     @Override
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
-    public String autoCreate(Long courseGroupId, String courseGroupType) throws Exception {
+    public String autoCreate(Long courseGroupId, String courseGroupType, List<Long> noGroupJoinUserIds) throws Exception {
         //获取课程组
         //获取课程组
         CourseGroup courseGroup = courseGroupService.getById(courseGroupId);
         CourseGroup courseGroup = courseGroupService.getById(courseGroupId);
         if (courseGroup.getTeacherId() == null) {
         if (courseGroup.getTeacherId() == null) {
             return null;
             return null;
         }
         }
-        //获取学员列表
-        Set<Long> studentIds = courseScheduleStudentPaymentDao.queryStudentIds(courseGroupId, courseGroupType);
+        //获取学员列表,按购买时间顺序升序排列返回
+        List<Long> studentIds = courseScheduleStudentPaymentDao.queryStudentIds(courseGroupId, courseGroupType);
+        // studentIds集合中所有null元素移除
         studentIds.removeAll(Collections.singleton(null));
         studentIds.removeAll(Collections.singleton(null));
         if (CollectionUtils.isEmpty(studentIds)) {
         if (CollectionUtils.isEmpty(studentIds)) {
             return null;
             return null;
@@ -391,7 +421,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         Date now = new Date();
         Date now = new Date();
         Long teacherId = courseGroup.getTeacherId();
         Long teacherId = courseGroup.getTeacherId();
         //保存老师学员关联的通讯录xz
         //保存老师学员关联的通讯录xz
-        imUserFriendService.saveUserFriend(teacherId, studentIds);
+        imUserFriendService.saveUserFriend(teacherId, Sets.newHashSet(studentIds));
 
 
         //创建群聊
         //创建群聊
         ImGroup imGroup = new ImGroup();
         ImGroup imGroup = new ImGroup();
@@ -408,25 +438,48 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         imGroup.setCourseGroupId(courseGroupId);
         imGroup.setCourseGroupId(courseGroupId);
 //        this.baseMapper.insert(imGroup);
 //        this.baseMapper.insert(imGroup);
 
 
-
         String groupId = createImGroup(imGroup);
         String groupId = createImGroup(imGroup);
-//        // 添加学生
-        List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId, studentIds,
-                ImGroupMemberRoleType.STUDENT);
-        List<com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember> groupMemberList = Lists.newArrayList();
-        for (ImGroupMember groupMember : groupMembers) {
-            groupMemberList.add(com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember.builder()
-                    .groupId(groupMember.getGroupId())
-                    .userId(groupMember.getUserId())
-                    .clientType(groupMember.getRoleType().getCode())
-                    .avatar(groupMember.getAvatar())
-                    .nickname(groupMember.getNickname())
-                    .isAdmin(groupMember.getIsAdmin())
-                    .imUserId(getImUserId(groupMember.getUserId().toString(), groupMember.getRoleType().getCode()))
-                    .roleType(groupMember.getRoleType().getCode())
-                    .build());
+
+        // 直播课、琴房课校验群成员人数限制
+        if (CourseScheduleEnum.PIANO_ROOM_CLASS.getCode().equals(courseGroupType)
+            || CourseScheduleEnum.LIVE.getCode().equals(courseGroupType)) {
+
+            // 增加群成员人数限制,若超过限制则不添加到群组
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(config) && Integer.parseInt(config.getParamValue()) > 0) {
+                int groupMemberLimit = Integer.parseInt(config.getParamValue());
+                if ((CollectionUtils.size(studentIds) + 1) > groupMemberLimit) {
+
+                    // 已加入群组用户标记
+                    List<Long> userIds = Lists.newArrayList(studentIds);
+                    studentIds = userIds.subList(0, groupMemberLimit - 1);
+                    // 未加入群组用户标记
+                    noGroupJoinUserIds.addAll(userIds.subList(groupMemberLimit - 1, userIds.size()));
+                    // 重置用户入群加入标记
+                    courseScheduleStudentPaymentDao.updateGroupJoinStatus(courseGroupId, courseGroupType, false,
+                        noGroupJoinUserIds);
+                }
+            }
+        }
+
+        if (!studentIds.isEmpty()) {
+            // 添加学生
+            List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMembers(groupId, Sets.newHashSet(studentIds), ImGroupMemberRoleType.STUDENT);
+            List<com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember> groupMemberList = Lists.newArrayList();
+            for (ImGroupMember groupMember : groupMembers) {
+                groupMemberList.add(com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupMemberWrapper.ImGroupMember.builder()
+                        .groupId(groupMember.getGroupId())
+                        .userId(groupMember.getUserId())
+                        .clientType(groupMember.getRoleType().getCode())
+                        .avatar(groupMember.getAvatar())
+                        .nickname(groupMember.getNickname())
+                        .isAdmin(groupMember.getIsAdmin())
+                        .imUserId(getImUserId(groupMember.getUserId().toString(), groupMember.getRoleType().getCode()))
+                        .roleType(groupMember.getRoleType().getCode())
+                        .build());
+            }
+            imGroupCoreService.saveImGroupMemberList(groupId, groupMemberList);
         }
         }
-        imGroupCoreService.saveImGroupMemberList(groupId, groupMemberList);
         //处理本地群成员列表
         //处理本地群成员列表
         // 添加老师
         // 添加老师
 //        List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroupId, imGroup.getCreateBy(),
 //        List<ImGroupMember> groupMembers = imGroupMemberService.initGroupMember(imGroupId, imGroup.getCreateBy(),
@@ -436,7 +489,7 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
 //        this.rtcCreate(courseGroup.getTeacherId(), imGroupId, imGroup.getName(),imGroup.getImg());
 //        this.rtcCreate(courseGroup.getTeacherId(), imGroupId, imGroup.getName(),imGroup.getImg());
 //        //加入融云群
 //        //加入融云群
 //        imGroupMemberService.join(groupMembers, imGroupId);
 //        imGroupMemberService.join(groupMembers, imGroupId);
-        return groupId.toString();
+        return groupId;
     }
     }
 
 
 
 
@@ -612,6 +665,13 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
     public ImGroup findGroupInfoById(String groupId, Long userId) {
     public ImGroup findGroupInfoById(String groupId, Long userId) {
 
 
         ImGroup group = imGroupService.getById(groupId);
         ImGroup group = imGroupService.getById(groupId);
+        if (Objects.nonNull(group)) {
+            // 查询群成员人数限制
+            SysConfig byParamName = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(byParamName)) {
+                group.setGroupMemberLimit(Integer.parseInt(byParamName.getParamValue()));
+            }
+        }
 
 
         // 异步执行自动加入群组功能
         // 异步执行自动加入群组功能
         ThreadPool.getExecutor().submit(() -> {
         ThreadPool.getExecutor().submit(() -> {
@@ -664,6 +724,24 @@ public class ImGroupServiceImpl extends ServiceImpl<ImGroupDao, ImGroup> impleme
         return group;
         return group;
     }
     }
 
 
+    /**
+     * 获取群信息
+     *
+     * @param groupId 群ID
+     * @return ImGroup
+     */
+    @Override
+    public ImGroup getGroupById(String groupId) {
+        ImGroup group = imGroupService.getById(groupId);
+        if (Objects.nonNull(group)) {
+            // 查询群成员人数限制
+            SysConfig byParamName = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (Objects.nonNull(byParamName)) {
+                group.setGroupMemberLimit(Integer.parseInt(byParamName.getParamValue()));
+            }
+        }
+        return group;
+    }
 
 
 
 
     /**
     /**

+ 133 - 39
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ImUserFriendServiceImpl.java

@@ -15,24 +15,32 @@ import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
 import com.yonge.cooleshow.auth.config.CustomerServiceConfig;
 import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
 import com.yonge.cooleshow.biz.dal.dao.ImUserFriendDao;
+import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dao.TeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.dto.BasicUserInfo;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
 import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.enums.MK;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
 import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.CustomerService;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.ImUtil;
 import com.yonge.toolset.base.util.ImUtil;
 import io.rong.messages.BaseMessage;
 import io.rong.messages.BaseMessage;
 import io.rong.messages.ImgMessage;
 import io.rong.messages.ImgMessage;
 import io.rong.messages.TxtMessage;
 import io.rong.messages.TxtMessage;
-import io.rong.models.message.PrivateMessage;
 import io.rong.models.message.PushExt;
 import io.rong.models.message.PushExt;
-import io.rong.models.response.ResponseResult;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -41,13 +49,12 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Transactional;
 
 
 import javax.annotation.Resource;
 import javax.annotation.Resource;
-import java.text.MessageFormat;
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
@@ -78,6 +85,14 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
 
 
     @Autowired
     @Autowired
     private ImPluginContext imPluginContext;
     private ImPluginContext imPluginContext;
+    @Autowired
+    private StudentDao studentDao;
+    @Autowired
+    private SubjectService subjectService;
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+    @Autowired
+    private SysConfigService sysConfigService;
     @Override
     @Override
     public ImUserFriendDao getDao() {
     public ImUserFriendDao getDao() {
         return this.baseMapper;
         return this.baseMapper;
@@ -183,49 +198,71 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
 
 
     @Override
     @Override
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
-    public ImUserFriend getDetail(String imUserId, ClientEnum clientType) {
+    public ImUserFriendVO.ImUserFriend getDetail(String imUserId, ClientEnum clientType) {
 
 
         // 用户ID
         // 用户ID
         long userId = Long.parseLong(imGroupService.analysisImUserId(imUserId));
         long userId = Long.parseLong(imGroupService.analysisImUserId(imUserId));
 
 
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(userId);
         BasicUserInfo basicUserInfo = teacherDao.getBasicUserInfo(userId);
-        if (sysUser != null && sysUser.getId() != null) {
-
-            ImUserFriend imUserFriend = lambdaQuery()
-                    .eq(ImUserFriend::getUserId, sysUser.getId())
-                    .eq(ImUserFriend::getClientType, clientType)
-                    .eq(ImUserFriend::getFriendId, userId)
-                    .one();
-            if (Objects.nonNull(imUserFriend)) {
-                //更新当前用户关联的该用户的详情信息
-                imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
-                imUserFriend.setFriendNickname(basicUserInfo.getUsername());
-                imUserFriend.setUpdateTime(new Date());
-                baseMapper.updateById(imUserFriend);
-
-                // 设置融云IM好友ID
-                imUserFriend.setImFriendId(imUserId);
-
-                return imUserFriend;
+        if (basicUserInfo == null) {
+            throw new BizException("无效的用户");
+        }
+
+        String friendClientType = imGroupService.analysisImUserClient(imUserId);
+        ImUserFriend imUserFriend = lambdaQuery()
+                .eq(ImUserFriend::getUserId, sysUser.getId())
+                .eq(ImUserFriend::getClientType, clientType)
+                .eq(ImUserFriend::getFriendId, userId)
+                .eq(ImUserFriend::getFriendType, ClientEnum.valueOf(friendClientType))
+                .one();
+        if (Objects.nonNull(imUserFriend)) {
+            //更新当前用户关联的该用户的详情信息
+            imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
+            imUserFriend.setFriendNickname(basicUserInfo.getUsername());
+            imUserFriend.setUpdateTime(new Date());
+            baseMapper.updateById(imUserFriend);
+
+            // 设置融云IM好友ID
+            imUserFriend.setImFriendId(imUserId);
+        } else {
+            // 好友身份类型
+            ClientEnum friendType = ClientEnum.TEACHER;
+            if (ClientEnum.STUDENT.match(imGroupService.analysisImUserClient(imUserId))) {
+                friendType = ClientEnum.STUDENT;
             }
             }
+            // 返回当前登录用户信息
+            imUserFriend = new ImUserFriend();
+            imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
+            imUserFriend.setFriendNickname(basicUserInfo.getUsername());
+            imUserFriend.setFriendId(userId);
+            imUserFriend.setFriendType(friendType);
+            // 设置融云IM好友ID
+            imUserFriend.setImFriendId(imUserId);
         }
         }
 
 
-        // 好友身份类型
-        ClientEnum friendType = ClientEnum.TEACHER;
-        if (ClientEnum.STUDENT.match(imGroupService.analysisImUserClient(imUserId))) {
-            friendType = ClientEnum.STUDENT;
+        ImUserFriendVO.ImUserFriend result = JSON.parseObject(JSON.toJSONString(imUserFriend), ImUserFriendVO.ImUserFriend.class);
+        result.setFriendGender(basicUserInfo.getGender());
+
+        if (ClientEnum.STUDENT.getCode().equals(friendClientType)) {
+            StudentVo detail = studentDao.detail(userId);
+            if (detail != null && StringUtils.isNotEmpty(detail.getSubjectId())) {
+                List<Subject> subject = subjectService.findBySubjectByIdList(detail.getSubjectId());
+                String subjectName = subject.stream().map(Subject::getName).collect(Collectors.joining("、"));
+                result.setFriendSubjectName(subjectName);
+            }
+        } else if (ClientEnum.TEACHER.getCode().equals(friendClientType)) {
+            TeacherVo detail = teacherDao.detail(userId);
+            if (detail != null && StringUtils.isNotEmpty(detail.getSubjectId())) {
+                List<Subject> subject = subjectService.findBySubjectByIdList(detail.getSubjectId());
+                String subjectName = subject.stream().map(Subject::getName).collect(Collectors.joining("、"));
+                result.setFriendSubjectName(subjectName);
+            }
         }
         }
-        // 返回当前登录用户信息
-        ImUserFriend imUserFriend = new ImUserFriend();
-        imUserFriend.setFriendAvatar(basicUserInfo.getAvatar());
-        imUserFriend.setFriendNickname(basicUserInfo.getUsername());
-        imUserFriend.setFriendId(userId);
-        imUserFriend.setFriendType(friendType);
-        // 设置融云IM好友ID
-        imUserFriend.setImFriendId(imUserId);
-
-        return imUserFriend;
+        VipCardRecordWrapper.UserVip userVip = vipCardRecordService.UserVipInfo(userId, ClientEnum.valueOf(friendClientType));
+        result.setUserVip(userVip);
+        result.setFriendBirthdate(basicUserInfo.getBirthdate());
+        return result;
     }
     }
 
 
     /**
     /**
@@ -280,12 +317,12 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
         try {
         try {
 
 
             // 设置默认值
             // 设置默认值
-            String customerMessage = customerServiceConfig.getCustomerMessage();
+            String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
             if (StringUtils.isEmpty(customerMessage)) {
             if (StringUtils.isEmpty(customerMessage)) {
                 customerMessage = MK.IM_SYS_FRIEND;
                 customerMessage = MK.IM_SYS_FRIEND;
             }
             }
 
 
-            String customerTitle = customerServiceConfig.getCustomerTitle();
+            String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
             if (StringUtils.isEmpty(customerTitle)) {
             if (StringUtils.isEmpty(customerTitle)) {
                 customerTitle = MK.IM_SYS_TITLE;
                 customerTitle = MK.IM_SYS_TITLE;
             }
             }
@@ -332,6 +369,63 @@ public class ImUserFriendServiceImpl extends ServiceImpl<ImUserFriendDao, ImUser
     }
     }
 
 
     /**
     /**
+     * 与客服建立好友关系时,客服给好友发送消息
+     */
+    @Override
+    public void sendCustomerServiceAddFriendMessage(Long customerServiceId, String sendTitle, String sendMessage, List<Long> friendIds, ClientEnum friendType) {
+
+        if (customerServiceId == null || CollectionUtils.isEmpty(friendIds)) {
+            return;
+        }
+
+        try {
+            if (StringUtils.isEmpty(sendMessage)) {
+                sendMessage = MK.IM_SYS_FRIEND;
+            }
+
+            if (StringUtils.isEmpty(sendTitle)) {
+                sendTitle = MK.IM_SYS_TITLE;
+            }
+
+            // 拓展消息
+            PushExt pushExt = PushExt.build(sendTitle, 1,
+                    new PushExt.HW("channelId", "NORMAL"), new PushExt.VIVO("1"),
+                    new PushExt.APNs("", ""),
+                    new PushExt.OPPO(""));
+
+
+            List<String> targetIds = friendIds.stream().map(n -> imGroupService.getImUserId(n, friendType)).collect(Collectors.toList());
+            MessageWrapper.PrivateMessage build = MessageWrapper.PrivateMessage.builder()
+                    .senderId(imGroupService.getImUserId(customerServiceId.toString(), ClientEnum.TEACHER.getCode()))
+                    .targetIds(targetIds)
+                    //.objectName(txtMessage.getType())
+                    //.rongCloueMessage(txtMessage)
+                    .pushExt(JSON.toJSONString(pushExt))
+                    .includeSender(0)
+                    .build();
+
+
+            if (TencentCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
+                // 腾讯IM消息
+                TencentRequest.MessageBody message = TencentRequest.MessageBody.builder()
+                        .msgType(ETencentMessage.TIMTextElem.name())
+                        .msgContent(TencentRequest.TextMessageBody.builder().text(sendMessage).build())
+                        .build();
+
+                Boolean ret = imPluginContext.getPluginService().sendPrivateMessage(build.objectName(message.getMsgType()).tencentMessage(message));
+                log.info("registerUserBindCustomerService GROUP tencentCloud senderId={}, ret={}", build.getSenderId(), ret);
+            } else {
+                // 融云IM消息
+                TxtMessage message = new TxtMessage(sendMessage, "");
+                Boolean ret = imPluginContext.getPluginService().sendPrivateMessage(build.objectName(message.getType()).rongCloueMessage(message));
+                log.info("registerUserBindCustomerService GROUP rongCloud senderId={}, ret={}", build.getSenderId(), ret);
+            }
+        } catch (Exception e) {
+            log.error("registerUserBindCustomerService userId={}", customerServiceId, e);
+        }
+    }
+
+    /**
      * 发送系统客服消息
      * 发送系统客服消息
      *
      *
      * @param sender 发送者
      * @param sender 发送者

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

@@ -3,11 +3,13 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dao.UserOrderDao;
 import com.yonge.cooleshow.biz.dal.dto.ActivityPlanRewardDto;
 import com.yonge.cooleshow.biz.dal.dto.ActivityPlanRewardDto;
-import com.yonge.cooleshow.biz.dal.dto.VipSubmitReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
+import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
@@ -21,15 +23,14 @@ import com.yonge.cooleshow.biz.dal.vo.*;
 
 
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
-import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
 import com.yonge.cooleshow.common.enums.ActivityShareEnum;
-import com.yonge.cooleshow.common.enums.RewardTypeEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
-import com.yonge.toolset.base.string.MessageFormatter;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.date.DateUtil;
+import org.joda.time.DateTime;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.stereotype.Service;
@@ -37,9 +38,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
 import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
 import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
+import org.springframework.transaction.annotation.Transactional;
 
 
 import java.math.BigDecimal;
 import java.math.BigDecimal;
 import java.util.*;
 import java.util.*;
+import java.util.stream.Collectors;
 
 
 
 
 @Service
 @Service
@@ -66,6 +69,9 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     private UserOrderService userOrderService;
     private UserOrderService userOrderService;
 
 
     @Autowired
     @Autowired
+    private UserOrderDao userOrderDao;
+
+    @Autowired
     private RedisCacheService redisCacheService;
     private RedisCacheService redisCacheService;
 
 
     @Override
     @Override
@@ -88,16 +94,32 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     public HttpResponseResult<OrderCreateRes> orderCreate(OrderReq.OrderReqInfo orderReqInfo) {
     public HttpResponseResult<OrderCreateRes> orderCreate(OrderReq.OrderReqInfo orderReqInfo) {
         MemberPriceSettingsVo detail = detail(Long.parseLong(orderReqInfo.getBizContent().toString()));
         MemberPriceSettingsVo detail = detail(Long.parseLong(orderReqInfo.getBizContent().toString()));
         if (null == detail) {
         if (null == detail) {
-            return HttpResponseResult.failed("未找到会员卡信息");
+            return HttpResponseResult.failed("产品信息已更新,请重新选择");
+        }
+
+        if (!orderReqInfo.getOrderType().name().equals(detail.getVipType().name())) {
+            return HttpResponseResult.failed("产品信息已更新,请重新选择");
         }
         }
 
 
+        if (Boolean.FALSE.equals(detail.getStatus())) {
+            return HttpResponseResult.failed("产品信息已更新,请重新选择");
+        }
+
+
+        // 判断是否有待支付订单 如果有返回不可下单
+        checkOrder(orderReqInfo.getOrderClient(), orderReqInfo.getOrderType().name(), orderReqInfo.getUserId());
+
+
+        checkVip(detail, orderReqInfo.getVipEndDays(), orderReqInfo.getUserId(), orderReqInfo.getOrderClient(), orderReqInfo.getGoodsNum(),orderReqInfo.getBizPrice());
+
         OrderCreateRes orderCreateRes = new OrderCreateRes();
         OrderCreateRes orderCreateRes = new OrderCreateRes();
         BigDecimal couponAmount = BigDecimal.ZERO;
         BigDecimal couponAmount = BigDecimal.ZERO;
         ActivityPlanVo activityPlanVo = activityPlanService.detail(orderReqInfo.getActivityId());
         ActivityPlanVo activityPlanVo = activityPlanService.detail(orderReqInfo.getActivityId());
 
 
         if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
         if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
             for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
             for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
-                if (activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
+                if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(detail.getVipType().getCode())
+                && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
                     couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
                     couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
                     orderCreateRes.setActivityId(activityPlanVo.getId());
                     orderCreateRes.setActivityId(activityPlanVo.getId());
                     orderCreateRes.setRewardId(activityPlanRewardDto.getActivityReward().getId());
                     orderCreateRes.setRewardId(activityPlanRewardDto.getActivityReward().getId());
@@ -110,14 +132,70 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         orderCreateRes.setMerchId(0l);
         orderCreateRes.setMerchId(0l);
         orderCreateRes.setBizId(detail.getId());
         orderCreateRes.setBizId(detail.getId());
         orderCreateRes.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
         orderCreateRes.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
-        orderCreateRes.setGoodNum(1);
-        orderCreateRes.setOriginalPrice(detail.getOriginalPrice());
-        orderCreateRes.setCouponAmount(couponAmount);
-        orderCreateRes.setExpectPrice(detail.getSalePrice());
+        orderCreateRes.setGoodNum(orderReqInfo.getGoodsNum());
+        orderCreateRes.setOriginalPrice(detail.getOriginalPrice().multiply(new BigDecimal(orderReqInfo.getGoodsNum())));
+        orderCreateRes.setCouponAmount(couponAmount.multiply(new BigDecimal(orderReqInfo.getGoodsNum())));
+        orderCreateRes.setExpectPrice(detail.getSalePrice().multiply(new BigDecimal(orderReqInfo.getGoodsNum())));
         orderCreateRes.setSourceType(SourceTypeEnum.PLATFORM);
         orderCreateRes.setSourceType(SourceTypeEnum.PLATFORM);
+        UserPaymentOrderWrapper.VipDays vipDays = new UserPaymentOrderWrapper.VipDays();
+        vipDays.setVipEndDays(orderReqInfo.getVipEndDays());
+        orderCreateRes.setBizJson(JSON.toJSONString(vipDays));
         return HttpResponseResult.succeed(orderCreateRes);
         return HttpResponseResult.succeed(orderCreateRes);
     }
     }
 
 
+    private void checkVip(MemberPriceSettingsVo detail, Integer vipDays, Long userId, ClientEnum client, Integer num, BigDecimal bizPrice) {
+        // 判断会员剩余天数是否改变
+        if (detail.getVipType() == EVipType.SVIP && vipDays != null && vipDays > 0) {
+            VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(userId, client);
+            if (!userVip.getVipEndDays().equals(vipDays)) {
+                throw new BizException(998, "您当前VIP天数更新,请刷新后尝试");
+            }
+            // 判断能不能升级
+            // 按时间区分 个数
+            int days = getSvipDays(detail, num, userVip);
+            if (days < userVip.getVipEndDays()) {
+                throw new BizException(998, "您当前VIP天数更新,请刷新后尝试");
+            }
+        }
+        if (bizPrice !=null && detail.getSalePrice().compareTo(bizPrice) !=0) {
+            throw new BizException(999, "产品信息已更新,请重新选择");
+
+        }
+    }
+
+    private int getSvipDays(MemberPriceSettingsVo detail, Integer num, VipCardRecordWrapper.UserVip userVip) {
+        Integer timeNum = num;
+
+        // 判断当前时间 加 一段时间后,和当前天数比较
+        Date svipStartDate = new Date();
+        if (userVip.getSvipEndDate() != null) {
+            svipStartDate = userVip.getSvipEndDate();
+        }
+
+        DateTime dateTime = DateTime.parse(DateUtil.format(svipStartDate, "yyyy-MM-dd"))
+            .withHourOfDay(23)
+            .withMinuteOfHour(59)
+            .withSecondOfMinute(59)
+            .withMillisOfSecond(0);
+        if (PeriodEnum.DAY.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusDays(timeNum);
+        } else if (PeriodEnum.MONTH.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusMonths(timeNum);
+        } else if (PeriodEnum.QUARTERLY.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusMonths(3 * timeNum);
+        } else if (PeriodEnum.YEAR_HALF.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusMonths(6 * timeNum);
+        } else if (PeriodEnum.YEAR.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusYears(timeNum);
+        } else if (PeriodEnum.PERPETUAL.equals(detail.getPeriod())) {
+            dateTime=dateTime.plusYears(100);
+        }
+        Date date = dateTime.toDate();
+        // 比较两个时间 天数差
+        int days = DateUtil.daysBetween(svipStartDate, date);
+        return days;
+    }
+
     @Override
     @Override
     public void orderSuccess(UserOrderDetailVo orderDetailVo) {
     public void orderSuccess(UserOrderDetailVo orderDetailVo) {
         orderSuccess(orderDetailVo,true);
         orderSuccess(orderDetailVo,true);
@@ -126,25 +204,101 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     @Override
     @Override
     public void orderSuccess(UserOrderDetailVo orderDetailVo,boolean messageFlag) {
     public void orderSuccess(UserOrderDetailVo orderDetailVo,boolean messageFlag) {
 
 
-        VipCardRecord vipCardRecord = vipCardRecordService.buildVipCardRecordByOrderDetail(orderDetailVo);
+        if (null == orderDetailVo) {
+            return;
+        }
+        MemberPriceSettingsVo detail = detail(orderDetailVo.getBizId());
+
+
+        VipCardRecordWrapper.AddVipCardRecord addVipCardRecord = new VipCardRecordWrapper.AddVipCardRecord();
+
+        addVipCardRecord.setUserId(orderDetailVo.getUserId());
+        addVipCardRecord.setClientType(orderDetailVo.getOrderClient());
+        addVipCardRecord.setStatus(EVipRecordStatus.ADD);
+        addVipCardRecord.setVipType(detail.getVipType());
+        addVipCardRecord.setType(detail.getPeriod());
+        addVipCardRecord.setTimes(orderDetailVo.getGoodNum());
+        addVipCardRecord.setSendMsg(false);
+        addVipCardRecord.setSourceType(SourceTypeEnum.ORDER);
+        addVipCardRecord.setCreateBy(orderDetailVo.getUserId());
+        addVipCardRecord.setOrderNo(orderDetailVo.getOrderNo());
+        addVipCardRecord.setSubOrderNo(orderDetailVo.getSubOrderNo());
+        addVipCardRecord.setVipCardId(orderDetailVo.getBizId());
+        addVipCardRecord.setOrderFlag(true);
+
+        // 判断转换天数
+
+        VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(orderDetailVo.getUserId(), orderDetailVo.getOrderClient());
+        int svipDays = getSvipDays(detail, orderDetailVo.getGoodNum(), userVip);
+        if (detail.getVipType() == EVipType.SVIP &&userVip.getVipEndDays() !=null && svipDays >=userVip.getVipEndDays()) {
+            addVipCardRecord.setVipDays(userVip.getVipEndDays());
+            if (userVip.getVipType() == EVipType.VIP) {
+                addVipCardRecord.setVipDays(Math.max(userVip.getVipEndDays()-1,0));
+            }
+        }
+
+        addVipCardRecord.setReason("会员购买");
+        vipCardRecordService.add(addVipCardRecord);
 
 
-        UserVipInfoVo userVipInfoVo = getUserVipInfoVo(vipCardRecord);
         //会员购买消息推送
         //会员购买消息推送
         if (messageFlag) {
         if (messageFlag) {
-            authSend(userVipInfoVo.getUserId(), userVipInfoVo.getPhone(), DateUtil.format(vipCardRecord.getEndTime(), DateUtil.DEFAULT_PATTERN), orderDetailVo.getOrderClient());
+
+            SysUser sysUser = sysUserFeignService.queryUserById(orderDetailVo.getUserId());
+            if (sysUser == null) {
+                return;
+            }
+
+            // 按时间区分 个数
+            Integer timeNum = 0;
+            PeriodEnum periodType  = null;
+            if (PeriodEnum.DAY.equals(detail.getPeriod())) {
+                timeNum = 1;
+                periodType = PeriodEnum.DAY;
+            } else if (PeriodEnum.MONTH.equals(detail.getPeriod())) {
+                timeNum = 1;
+                periodType = PeriodEnum.MONTH;
+            } else if (PeriodEnum.QUARTERLY.equals(detail.getPeriod())) {
+                timeNum = 3;
+                periodType = PeriodEnum.MONTH;
+            } else if (PeriodEnum.YEAR_HALF.equals(detail.getPeriod())) {
+                timeNum = 6;
+                periodType = PeriodEnum.MONTH;
+            } else if (PeriodEnum.YEAR.equals(detail.getPeriod())) {
+                timeNum = 1;
+                periodType = PeriodEnum.YEAR;
+            } else if (PeriodEnum.PERPETUAL.equals(detail.getPeriod())) {
+                timeNum = 1;
+                periodType = PeriodEnum.PERPETUAL;
+            }
+            if (periodType == null) {
+                return;
+            }
+            String s = timeNum + periodType.getMsg() + addVipCardRecord.getVipType().getName();
+            if (PeriodEnum.PERPETUAL.equals(detail.getPeriod())) {
+                s =addVipCardRecord.getVipType().getName();
+            }
+            authSend(sysUser.getId(), sysUser.getPhone(), s, orderDetailVo.getOrderClient());
         }
         }
     }
     }
 
 
 
 
     @Override
     @Override
+    @Transactional
     public void activityReward(Long userId, ClientEnum client, ActivityReward activityReward, Long activityId,String activityName) {
     public void activityReward(Long userId, ClientEnum client, ActivityReward activityReward, Long activityId,String activityName) {
 
 
-        VipCardRecord vipCardRecord = vipCardRecordService.buildVipCardRecordByOrderDetail(userId,client,activityReward,activityId,activityName);
-        if (vipCardRecord == null) {
-            return;
-        }
+        VipCardRecordWrapper.AddVipCardRecord addVipCardRecord = new VipCardRecordWrapper.AddVipCardRecord();
+
+        addVipCardRecord.setUserId(userId);
+        addVipCardRecord.setClientType(client);
+        addVipCardRecord.setStatus(EVipRecordStatus.ADD);
+        addVipCardRecord.setVipType(EVipType.valueOf(activityReward.getRewardType().name()));
+        addVipCardRecord.setType(PeriodEnum.valueOf(activityReward.getUnit().name()));
+        addVipCardRecord.setTimes(activityReward.getNum());
+        addVipCardRecord.setSendMsg(false);
+        addVipCardRecord.setCreateBy(userId);
+        addVipCardRecord.setSourceType(SourceTypeEnum.ACTIVITY);
+        vipCardRecordService.add(addVipCardRecord);
 
 
-        getUserVipInfoVo(vipCardRecord);
     }
     }
 
 
     private UserVipInfoVo getUserVipInfoVo(VipCardRecord vipCardRecord) {
     private UserVipInfoVo getUserVipInfoVo(VipCardRecord vipCardRecord) {
@@ -212,19 +366,20 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         return result;
         return result;
     }
     }
 
 
-    @Override
-    public Boolean addVip(VipSubmitReq vipSubmitReq, ClientEnum client, SysUser sysUser) {
-
-        VipCardRecord vipCardRecord = vipCardRecordService.getVipCardRecord(vipSubmitReq.getUserId(), client, null, null, vipSubmitReq.getType().toString(),
-                            null, vipSubmitReq.getTimes(),SourceTypeEnum.PLATFORM, sysUser.getId(), vipSubmitReq.getReason());
-
-        getUserVipInfoVo(vipCardRecord);
-
-        // 发消息
-        sendAddVipMessage(vipSubmitReq.getUserId(),sysUser.getPhone(),client,vipSubmitReq.getTimes(),vipSubmitReq.getType(),vipSubmitReq.getReason());
-
-        return true;
-    }
+//    @Deprecated
+//    @Override
+//    public Boolean addVip(VipSubmitReq vipSubmitReq, ClientEnum client, SysUser sysUser) {
+//
+//        VipCardRecord vipCardRecord = vipCardRecordService.getVipCardRecord(vipSubmitReq.getUserId(), client, null, null, vipSubmitReq.getType().toString(),
+//                            null, vipSubmitReq.getTimes(),SourceTypeEnum.PLATFORM, sysUser.getId(), vipSubmitReq.getReason());
+//
+//        getUserVipInfoVo(vipCardRecord);
+//
+//        // 发消息
+//        sendAddVipMessage(vipSubmitReq.getUserId(),sysUser.getPhone(),client,vipSubmitReq.getTimes(),vipSubmitReq.getType(),vipSubmitReq.getReason());
+//
+//        return true;
+//    }
 
 
     @Override
     @Override
     public MemberPriceVo getVipShare(MemberPriceSettingsSearch query) {
     public MemberPriceVo getVipShare(MemberPriceSettingsSearch query) {
@@ -248,7 +403,8 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
 
 
         for (ActivityPlanRewardDto activityPlanRewardDto : activityPlan.getActivityRewardList()) {
         for (ActivityPlanRewardDto activityPlanRewardDto : activityPlan.getActivityRewardList()) {
             for (MemberPriceSettingsVo memberPriceSettingsVo : memberPriceSettingsVos) {
             for (MemberPriceSettingsVo memberPriceSettingsVo : memberPriceSettingsVos) {
-                if (memberPriceSettingsVo.getPeriod().getCode().equals( activityPlanRewardDto.getActivityReward().getUnit().getCode())) {
+                if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(memberPriceSettingsVo.getVipType().getCode())
+                    && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(memberPriceSettingsVo.getPeriod().getCode())) {
                     memberPriceSettingsVo.setDiscount(YesOrNoEnum.YES);
                     memberPriceSettingsVo.setDiscount(YesOrNoEnum.YES);
                     memberPriceSettingsVo.setDiscountPrice(activityPlanRewardDto.getActivityReward().getDiscountPrice());
                     memberPriceSettingsVo.setDiscountPrice(activityPlanRewardDto.getActivityReward().getDiscountPrice());
                 }
                 }
@@ -261,14 +417,29 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
     public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
     public void orderCreate(UserPaymentOrderWrapper.OrderGoodsInfo orderGoodsInfo) {
         MemberPriceSettingsVo detail = detail(Long.parseLong(orderGoodsInfo.getBizContent().toString()));
         MemberPriceSettingsVo detail = detail(Long.parseLong(orderGoodsInfo.getBizContent().toString()));
         if (null == detail) {
         if (null == detail) {
-            throw new BizException("未找到会员卡信息");
+            throw new BizException(999,"产品信息已更新,请重新选择");
+        }
+
+        if (!orderGoodsInfo.getGoodType().name().equals(detail.getVipType().name())) {
+            throw new BizException(999,"产品信息已更新,请重新选择");
+        }
+        if (Boolean.FALSE.equals(detail.getStatus())) {
+            throw new BizException(999,"产品信息已更新,请重新选择");
         }
         }
+
+
+        checkOrder(orderGoodsInfo.getPaymentClient(), detail.getVipType().name(), orderGoodsInfo.getUserId());
+
+        // 判断会员剩余天数是否改变
+        checkVip(detail, orderGoodsInfo.getVipEndDays(), orderGoodsInfo.getUserId(), orderGoodsInfo.getPaymentClient(), orderGoodsInfo.getGoodNum(), orderGoodsInfo.getBizPrice());
+
         BigDecimal couponAmount = BigDecimal.ZERO;
         BigDecimal couponAmount = BigDecimal.ZERO;
         ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
         ActivityPlanVo activityPlanVo = activityPlanService.detail(orderGoodsInfo.getActivityId());
 
 
         if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
         if (activityPlanVo != null && activityPlanVo.getActivityState() == 1) {
             for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
             for (ActivityPlanRewardDto activityPlanRewardDto : activityPlanVo.getActivityRewardList()) {
-                if (activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
+                if (activityPlanRewardDto.getActivityReward().getRewardType().getCode().equals(detail.getVipType().getCode())
+                    && activityPlanRewardDto.getActivityReward().getUnit().getCode().equals(detail.getPeriod().getCode())) {
                     couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
                     couponAmount = activityPlanRewardDto.getActivityReward().getDiscountPrice();
                     break;
                     break;
                 }
                 }
@@ -281,13 +452,16 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         userOrderDetail.setMerchId(0l);
         userOrderDetail.setMerchId(0l);
         userOrderDetail.setBizId(detail.getId());
         userOrderDetail.setBizId(detail.getId());
         userOrderDetail.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
         userOrderDetail.setBizContent("会员卡购买-" + detail.getPeriod().getMsg());
-        userOrderDetail.setGoodNum(1);
-        userOrderDetail.setOriginalPrice(detail.getOriginalPrice());
-        userOrderDetail.setCouponAmount(couponAmount);
-        userOrderDetail.setExpectPrice(detail.getSalePrice());
+        userOrderDetail.setGoodNum(orderGoodsInfo.getGoodNum());
+        userOrderDetail.setOriginalPrice(detail.getOriginalPrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
+        userOrderDetail.setCouponAmount(couponAmount.multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
+        userOrderDetail.setExpectPrice(detail.getSalePrice().multiply(new BigDecimal(orderGoodsInfo.getGoodNum())));
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
         userOrderDetail.setActualPrice(userOrderDetail.getExpectPrice().subtract(couponAmount));
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
         orderGoodsInfo.setUserOrderDetail(userOrderDetail);
 
 
+        UserPaymentOrderWrapper.VipDays vipDays = new UserPaymentOrderWrapper.VipDays();
+        vipDays.setVipEndDays(orderGoodsInfo.getVipEndDays());
+        userOrderDetail.setBizJson(JSON.toJSONString(vipDays));
         userOrderDetail.setAccountConfig( teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
         userOrderDetail.setAccountConfig( teacherService.teacherSettlementFrom(null,orderGoodsInfo.getRecomUserId()).jsonString());
 
 
         // 设置金额入账去向
         // 设置金额入账去向
@@ -296,6 +470,19 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
 
 
     }
     }
 
 
+    private void checkOrder(ClientEnum orderGoodsInfo, String orderType, Long userId) {
+        // 判断是否有待支付订单 如果有返回不可下单
+        OrderSearch search = new OrderSearch();
+        search.setOrderClient(orderGoodsInfo.name());
+        search.setGoodType(Lists.newArrayList(GoodTypeEnum.VIP, GoodTypeEnum.SVIP).stream().map(GoodTypeEnum::name).collect(Collectors.joining(",")));
+        search.setUserId(userId);
+
+        UserOrderVo userOrderVo = userOrderDao.getPendingOrder(search);
+        if (null != userOrderVo) {
+            throw new BizException(997, "您有未支付订单,请先支付");
+        }
+    }
+
     private void sendAddVipMessage(Long userId,String phone, ClientEnum client, Integer times, PeriodEnum type, String reason) {
     private void sendAddVipMessage(Long userId,String phone, ClientEnum client, Integer times, PeriodEnum type, String reason) {
         try {
         try {
             Map<Long, String> receivers = new HashMap<>();
             Map<Long, String> receivers = new HashMap<>();
@@ -348,28 +535,28 @@ public class MemberPriceSettingsServiceImpl extends ServiceImpl<MemberPriceSetti
         receivers.put(userId, phone);
         receivers.put(userId, phone);
 
 
         // 判断是否是机构学生 机构学生推送走另一个
         // 判断是否是机构学生 机构学生推送走另一个
-        Student student = studentService.getById(userId);
-        if (clientEnum.equals(ClientEnum.STUDENT) && student != null && student.getTenantId() != null && student.getTenantId() >0) {
-            try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TENANT_VIP_BUY,
-                        receivers, null, 0, null, ClientEnum.TENANT_STUDENT.getCode(),param1);
-            } catch (Exception e) {
-                log.error("会员购买极光消息推送异常,userId={}", userId);
-            }
-        } else {
-            try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.VIP_BUY_SUCCESS,
-                        receivers, null, 0, null, clientEnum.getCode(), param1);
-            } catch (Exception e) {
-                log.error("会员购买极光消息推送异常,userId={}", userId);
+
+        try {
+            MessageTypeEnum messageTypeEnum = MessageTypeEnum.NEW_VIP_BUY_SUCCESS;
+            if (clientEnum == ClientEnum.TEACHER) {
+                messageTypeEnum= MessageTypeEnum.NEW_TEACHER_VIP_BUY_SUCCESS;
             }
             }
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, messageTypeEnum,
+                    receivers, null, 0, null, clientEnum.getCode(), param1);
+        } catch (Exception e) {
+            log.error("会员购买极光消息推送异常,userId={}", userId);
+        }
 
 
-            try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIP_BUY_SUCCESS,
-                        receivers, null, 0, null, clientEnum.getCode(), param1);
-            } catch (Exception e) {
-                log.error("会员购买短信消息推送异常,userId={}", userId);
+        try {
+
+            MessageTypeEnum messageTypeEnum = MessageTypeEnum.SMS_NEW_VIP_BUY_SUCCESS;
+            if (clientEnum == ClientEnum.TEACHER) {
+                messageTypeEnum= MessageTypeEnum.SMS_TEACHER_NEW_VIP_BUY_SUCCESS;
             }
             }
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageTypeEnum,
+                    receivers, null, 0, null, clientEnum.getCode(), param1);
+        } catch (Exception e) {
+            log.error("会员购买短信消息推送异常,userId={}", userId);
         }
         }
 
 
     }
     }

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

@@ -254,24 +254,46 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
     }
     }
 
 
     @Override
     @Override
-    public IPage<MusicSheetVo> queryRelatedList(IPage<MusicSheetVo> page, Long albumId, Long musicSheetId) {
+    public IPage<MusicSheetVo> queryRelatedList(IPage<MusicSheetVo> page, MusicSheetRelatedQueryInfo queryInfo) {
 
 
-        if (albumId == null) {
+
+        MusicSheet musicSheet = baseMapper.selectById(queryInfo.getMusicSheetId());
+        if (queryInfo.getAlbumId() == null) {
             // 查询专辑下的所有曲目
             // 查询专辑下的所有曲目
 
 
-            MusicSheet musicSheet = baseMapper.selectById(musicSheetId);
 
 
             if (musicSheet != null) {
             if (musicSheet != null) {
                 MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
                 MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
                 query.setMusicTagIds(musicSheet.getMusicTag());
                 query.setMusicTagIds(musicSheet.getMusicTag());
                 query.setAuditVersion(musicSheet.getAuditVersion());
                 query.setAuditVersion(musicSheet.getAuditVersion());
+                query.setMusicSheetType(musicSheet.getMusicSheetType());
+                if (queryInfo.getSubjectId() !=null) {
+                    query.setSubjectIdList(Lists.newArrayList(queryInfo.getSubjectId()));
+                }
+                query.setState(YesOrNoEnum.YES);
+                query.setProviderType(SourceTypeEnum.PLATFORM);
+                query.setExcludeMusicIds(Lists.newArrayList(queryInfo.getMusicSheetId()));
+                if (StringUtils.isNotBlank(musicSheet.getMusicSubject())) {
+                    List<Long> subjectIds = Arrays.stream(musicSheet.getMusicSubject().split(",")).filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());
+                    query.setMustMatchSubjectIds(subjectIds);
+                }
                 return page.setRecords(baseMapper.selectPage(page, query));
                 return page.setRecords(baseMapper.selectPage(page, query));
             }
             }
         } else {
         } else {
             // 查询带有当前曲目标签的所有曲目
             // 查询带有当前曲目标签的所有曲目
             MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
             MusicAlbumDetailSearch query = new MusicAlbumDetailSearch();
-            query.setId(albumId);
+            query.setId(queryInfo.getAlbumId());
+            query.setState(YesOrNoEnum.YES);
             query.setType(2);
             query.setType(2);
+            if (queryInfo.getSubjectId() !=null) {
+                query.setSubjectIdList(Lists.newArrayList(queryInfo.getSubjectId()));
+            }
+            query.setExcludeMusicIds(Lists.newArrayList(queryInfo.getMusicSheetId()));
+            if (StringUtils.isNotBlank(musicSheet.getMusicSubject())) {
+                List<Long> subjectIds = Arrays.stream(musicSheet.getMusicSubject().split(",")).filter(StringUtils::isNotBlank).map(Long::parseLong).collect(Collectors.toList());
+                query.setMustMatchSubjectIds(subjectIds);
+            }
+            query.setExcludeMusicIds(Lists.newArrayList(queryInfo.getMusicSheetId()));
             return page.setRecords(baseMapper.selectAlbumDetailPage(page, query));
             return page.setRecords(baseMapper.selectAlbumDetailPage(page, query));
         }
         }
         return null;
         return null;
@@ -670,6 +692,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                     List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(collect);
                     List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(collect);
                     if (CollectionUtils.isNotEmpty(musicSheetIds) && musicSheetIds.contains(detail.getId())) {
                     if (CollectionUtils.isNotEmpty(musicSheetIds) && musicSheetIds.contains(detail.getId())) {
                         detail.setPlay(YesOrNoEnum.YES);
                         detail.setPlay(YesOrNoEnum.YES);
+                        detail.setBuyed(true);
                     }
                     }
                 }
                 }
             } else if (ClientEnum.TEACHER == userType) {
             } else if (ClientEnum.TEACHER == userType) {
@@ -679,6 +702,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                     List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                     List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                     if (musicSheetIds.contains(detail.getId())) {
                     if (musicSheetIds.contains(detail.getId())) {
                         detail.setPlay(YesOrNoEnum.YES);
                         detail.setPlay(YesOrNoEnum.YES);
+                        detail.setBuyed(true);
                     }
                     }
                 }
                 }
             }
             }
@@ -707,6 +731,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 detail.setOrderNo(musicSheetPurchaseRecord.getOrderNo());
                 detail.setOrderNo(musicSheetPurchaseRecord.getOrderNo());
                 if (OrderStatusEnum.PAID.getCode().equals(musicSheetPurchaseRecord.getOrderStatus().getCode())) {
                 if (OrderStatusEnum.PAID.getCode().equals(musicSheetPurchaseRecord.getOrderStatus().getCode())) {
                     detail.setPlay(YesOrNoEnum.YES);
                     detail.setPlay(YesOrNoEnum.YES);
+                    detail.setBuyed(true);
                     return;
                     return;
                 }
                 }
             }
             }
@@ -721,12 +746,12 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             // 会员 判断是否为会员, 会员可播放
             // 会员 判断是否为会员, 会员可播放
             if (userType.equals(ClientEnum.STUDENT)) {
             if (userType.equals(ClientEnum.STUDENT)) {
                 StudentVo studentVo = studentService.detail(studentId);
                 StudentVo studentVo = studentService.detail(studentId);
-                if (studentVo != null && YesOrNoEnum.YES.getCode().equals(studentVo.getIsVip().getCode())) {
+                if (studentVo != null && studentVo.getUserVip().getVipType() !=EVipType.NOT_VIP) {
                     detail.setPlay(YesOrNoEnum.YES);
                     detail.setPlay(YesOrNoEnum.YES);
                 }
                 }
             } else if (userType.equals(ClientEnum.TEACHER)) {
             } else if (userType.equals(ClientEnum.TEACHER)) {
                 TeacherVo teacher = teacherService.detail(studentId);
                 TeacherVo teacher = teacherService.detail(studentId);
-                if (teacher != null && YesOrNoEnum.YES.getCode().equals(teacher.getIsVip().getCode())) {
+                if (teacher != null && teacher.getUserVip().getVipType() !=EVipType.NOT_VIP) {
                     detail.setPlay(YesOrNoEnum.YES);
                     detail.setPlay(YesOrNoEnum.YES);
                 }
                 }
             }
             }
@@ -760,6 +785,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                     .count();
                     .count();
             if (count > 0) {
             if (count > 0) {
                 detail.setPlay(YesOrNoEnum.YES);
                 detail.setPlay(YesOrNoEnum.YES);
+                detail.setBuyed(true);
                 return;
                 return;
             }
             }
         }
         }
@@ -773,7 +799,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(tenantAlbumIds);
                 List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByIds(tenantAlbumIds);
                 if (musicSheetIds.contains(detail.getId())) {
                 if (musicSheetIds.contains(detail.getId())) {
                     detail.setPlay(YesOrNoEnum.YES);
                     detail.setPlay(YesOrNoEnum.YES);
-                    return;
+                    detail.setBuyed(true);
                 }
                 }
             }
             }
         } else if (ClientEnum.TEACHER == userType) {
         } else if (ClientEnum.TEACHER == userType) {
@@ -783,7 +809,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                 List<Long> musicSheetIds = tenantAlbumMusicService.getMusicIdsByTenantIds(teacher.getTenantId());
                 if (musicSheetIds.contains(detail.getId())) {
                 if (musicSheetIds.contains(detail.getId())) {
                     detail.setPlay(YesOrNoEnum.YES);
                     detail.setPlay(YesOrNoEnum.YES);
-                    return;
+                    detail.setBuyed(true);
                 }
                 }
             }
             }
         }
         }
@@ -2370,6 +2396,20 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         return new ArrayList<>();
         return new ArrayList<>();
     }
     }
 
 
+    @Override
+    public IPage<MusicSheetVo> queryTenantRelatedList(IPage<Object> page, MusicSheetRelatedQueryInfo queryInfo) {
+
+        MusicSheet musicSheet = musicSheetDao.get(queryInfo.getMusicSheetId());
+        if (musicSheet == null) {
+            throw new BizException("曲目不存在");
+        }
+        queryInfo.setMusicSheetType(musicSheet.getMusicSheetType());
+        if (musicSheet.getMusicSheetType() == MusicSheetTypeEnum.CONCERT) {
+            queryInfo.setSubjectId(null);
+        }
+        return musicSheetDao.queryTenantRelatedList(page,queryInfo);
+    }
+
 
 
     private void syncMusicSheet(MusicSheet record, Date date) {
     private void syncMusicSheet(MusicSheet record, Date date) {
         List<MusicSheetAccompaniment> list = musicSheetAccompanimentService.lambdaQuery().eq(MusicSheetAccompaniment::getMusicSheetId, record.getId()).list();
         List<MusicSheetAccompaniment> list = musicSheetAccompanimentService.lambdaQuery().eq(MusicSheetAccompaniment::getMusicSheetId, record.getId()).list();

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

@@ -956,7 +956,12 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
     private void teacherShare(UserOrderDetailVo userPaymentOrder, BigDecimal shareFee) {
     private void teacherShare(UserOrderDetailVo userPaymentOrder, BigDecimal shareFee) {
         //获取账期时间
         //获取账期时间
         Date accountPeriodTime = userOrderService.getAccountPeriodTime(userPaymentOrder);
         Date accountPeriodTime = userOrderService.getAccountPeriodTime(userPaymentOrder);
-        AccountBizTypeEnum bizTypeEnum = AccountBizTypeEnum.valueOf(userPaymentOrder.getGoodType().getCode() + "_SHARE");
+        AccountBizTypeEnum bizTypeEnum;
+        if (userPaymentOrder.getGoodType() == GoodTypeEnum.SVIP) {
+            bizTypeEnum = AccountBizTypeEnum.VIP_SHARE;
+        } else {
+            bizTypeEnum = AccountBizTypeEnum.valueOf(userPaymentOrder.getGoodType().getCode() + "_SHARE");
+        }
         if (null != bizTypeEnum) {
         if (null != bizTypeEnum) {
             //插入分润老师账户变更记录-分润老师预收
             //插入分润老师账户变更记录-分润老师预收
             HttpResponseResult<UserAccountRecord> recomRecordRes = userAccountService.accountRecord(
             HttpResponseResult<UserAccountRecord> recomRecordRes = userAccountService.accountRecord(
@@ -1031,8 +1036,12 @@ public class PaymentDivMemberRecordServiceImpl extends ServiceImpl<PaymentDivMem
                 continue;
                 continue;
             }
             }
             String type = userPaymentOrder.getGoodType().getCode();
             String type = userPaymentOrder.getGoodType().getCode();
-            if (share) {
-                type = type + "_SHARE";
+            if (share ) {
+                if (type.equals(GoodTypeEnum.SVIP.name())) {
+                    type = AccountBizTypeEnum.VIP_SHARE.name();
+                } else {
+                    type = type + "_SHARE";
+                }
             }
             }
 
 
             AccountBizTypeEnum bizTypeEnum = AccountBizTypeEnum.valueOf(type);
             AccountBizTypeEnum bizTypeEnum = AccountBizTypeEnum.valueOf(type);

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

@@ -75,6 +75,7 @@ public class PlatformCashAccountRecordServiceImpl extends ServiceImpl<PlatformCa
         paramNames.add(AccountBizTypeEnum.ALBUM.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.VIP.getCode());
         paramNames.add(AccountBizTypeEnum.VIP.getCode());
+        paramNames.add(AccountBizTypeEnum.SVIP.getCode());
         paramNames.add(AccountBizTypeEnum.VIP_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.VIP_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.ACTI_REGIST.getCode());
         paramNames.add(AccountBizTypeEnum.ACTI_REGIST.getCode());
         paramNames.add(AccountBizTypeEnum.ACTI_REGIST_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.ACTI_REGIST_SHARE.getCode());

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

@@ -17,10 +17,7 @@ import com.yonge.cooleshow.biz.dal.dao.*;
 import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
-import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
-import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.mapper.SysUserMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
@@ -34,6 +31,7 @@ import com.yonge.cooleshow.biz.dal.vo.StudentHomeVo;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -116,6 +114,9 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
     @Autowired
     @Autowired
     private SysMessageService sysMessageService;
     private SysMessageService sysMessageService;
 
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
     @Override
     @Override
     public StudentDao getDao() {
     public StudentDao getDao() {
         return baseMapper;
         return baseMapper;
@@ -134,7 +135,16 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
     private TenantGroupAlbumMapper tenantGroupAlbumMapper;
     private TenantGroupAlbumMapper tenantGroupAlbumMapper;
     @Override
     @Override
     public StudentVo detail(Long userId) {
     public StudentVo detail(Long userId) {
-        return baseMapper.detail(userId);
+        StudentVo detail = baseMapper.detail(userId);
+        VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(userId, ClientEnum.STUDENT);
+        detail.setUserVip(userVip);
+        detail.setVipType(EUserVipType.NORMAL);
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.STUDENT.getCode());
+        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
+        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
+        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
+        detail.setVipType(vipType.getCurrentVipType());
+        return detail;
     }
     }
 
 
     @Override
     @Override
@@ -144,7 +154,26 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
 
 
     @Override
     @Override
     public IPage<StudentVo> selectPage(IPage<StudentVo> page, StudentSearch studentSearch) {
     public IPage<StudentVo> selectPage(IPage<StudentVo> page, StudentSearch studentSearch) {
-        return page.setRecords(baseMapper.selectPage(page, studentSearch));
+        List<StudentVo> records = baseMapper.selectPage(page, studentSearch);
+        for (StudentVo record : records) {
+            EUserVipType vipType = record.getVipType();
+            if (EUserVipType.NORMAL.equals(vipType)) {
+                record.setMembershipEndTime(Optional.ofNullable(record.getVipEndTime()).orElse(record.getSvipEndTime()));
+            }
+            if (EUserVipType.SVIP.equals(vipType)) {
+                Date perSvipEndTime = record.getPerSvipEndTime();
+                if (perSvipEndTime != null) {
+                    // 永久会员
+                    record.setMembershipEndTime(null);
+                } else {
+                    record.setMembershipEndTime(record.getSvipEndTime());
+                }
+            }
+            if (EUserVipType.VIP.equals(vipType)) {
+                record.setMembershipEndTime(record.getVipEndTime());
+            }
+        }
+        return page.setRecords(records);
     }
     }
 
 
     @Override
     @Override
@@ -190,6 +219,12 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         studentHomeVo.setMusicAlbumNum(null == total.getMusicAlbumNum() ? 0 : total.getMusicAlbumNum());
         studentHomeVo.setMusicAlbumNum(null == total.getMusicAlbumNum() ? 0 : total.getMusicAlbumNum());
         studentHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());
         studentHomeVo.setMusicSheetNum(null == total.getMusicSheetNum() ? 0 : total.getMusicSheetNum());
 
 
+        // 设置会员信息
+
+
+        studentHomeVo.setUserVip(vipCardRecordService.userVipInfo(user.getId(), ClientEnum.STUDENT));
+
+
         // IM聊天用户ID
         // IM聊天用户ID
         studentHomeVo.setImUserId(imGroupService.getImUserId(String.valueOf(detail.getUserId()), ClientEnum.STUDENT.name()));
         studentHomeVo.setImUserId(imGroupService.getImUserId(String.valueOf(detail.getUserId()), ClientEnum.STUDENT.name()));
 
 
@@ -284,6 +319,20 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
     @Override
     @Override
     public IPage<MyFollow> queryMyFollow(IPage<MyFollow> page, QueryMyFollowSearch query) {
     public IPage<MyFollow> queryMyFollow(IPage<MyFollow> page, QueryMyFollowSearch query) {
         List<MyFollow> teacherVos = baseMapper.queryMyFollow(page, query);
         List<MyFollow> teacherVos = baseMapper.queryMyFollow(page, query);
+        if (CollectionUtils.isEmpty(teacherVos)) {
+            return page.setRecords(teacherVos);
+        }
+
+        // 老师ID集合
+        List<Long> teacherIds = teacherVos.stream().filter(o -> o.getTeacher() != null).map(o -> o.getTeacher().getUserId()).collect(Collectors.toList());
+        Map<Long, EVipType> vipTypeMapByUserIds = vipCardRecordService.getVipTypeMapByUserIds(teacherIds, ClientEnum.TEACHER);
+        for (MyFollow teacherVo : teacherVos) {
+            teacherVo.setVipType(EVipType.NOT_VIP);
+            if (teacherVo.getTeacher() != null) {
+                teacherVo.setVipType(vipTypeMapByUserIds.getOrDefault(teacherVo.getTeacher().getUserId(),EVipType.NOT_VIP));
+            }
+        }
+
         return page.setRecords(teacherVos);
         return page.setRecords(teacherVos);
     }
     }
 
 
@@ -853,17 +902,11 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
             addBindUnBindRecord(student.getUserId(), student.getTenantId(), true);
             addBindUnBindRecord(student.getUserId(), student.getTenantId(), true);
         }
         }
 
 
-        //  与随机一个客服建立好友
-        String customerService = customerServiceConfig.getCustomerService();
-        if (StringUtils.isNotBlank(customerService)) {
-            List<String> phones = Arrays.stream(customerService.split(",")).collect(Collectors.toList());
-            Random rand = new Random();
-            String mobile = phones.get(rand.nextInt(phones.size()));
-            SysUser friend = sysUserMapper.findUserByPhone(mobile);
-            if (friend != null) {
-                imUserFriendService.registerUserBindCustomerService(student.getUserId(),
-                        Collections.singletonList(friend.getId()), ClientEnum.STUDENT);
-            }
+        //  与好友数量最少的客服建立好友关系
+        Teacher customerService = teacherDao.getCustomerServiceByFriendLeast();
+        if (customerService != null) {
+            imUserFriendService.registerUserBindCustomerService(student.getUserId(),
+                    Collections.singletonList(customerService.getUserId()), ClientEnum.STUDENT);
         }
         }
 
 
         // 加入机构小组群
         // 加入机构小组群

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

@@ -78,6 +78,10 @@ public class StudentTimeServiceImpl extends ServiceImpl<StudentTimeDao, StudentT
                 if (null == studentTime.getFirstVipTime() && GoodTypeEnum.VIP.equals(detailVo.getGoodType())) {
                 if (null == studentTime.getFirstVipTime() && GoodTypeEnum.VIP.equals(detailVo.getGoodType())) {
                     studentTime.setFirstVipTime(now);
                     studentTime.setFirstVipTime(now);
                 }
                 }
+
+                if (null == studentTime.getFirstVipTime() && GoodTypeEnum.SVIP.equals(detailVo.getGoodType())) {
+                    studentTime.setFirstSvipTime(now);
+                }
                 if (null == studentTime.getFirstPracticeTime() && GoodTypeEnum.PRACTICE.equals(detailVo.getGoodType())) {
                 if (null == studentTime.getFirstPracticeTime() && GoodTypeEnum.PRACTICE.equals(detailVo.getGoodType())) {
                     studentTime.setFirstPracticeTime(now);
                     studentTime.setFirstPracticeTime(now);
                 }
                 }
@@ -158,6 +162,10 @@ public class StudentTimeServiceImpl extends ServiceImpl<StudentTimeDao, StudentT
         if (GoodTypeEnum.VIP.equals(goodType) && null == studentTime.getFirstVipTime()) {
         if (GoodTypeEnum.VIP.equals(goodType) && null == studentTime.getFirstVipTime()) {
             studentTime.setFirstVipTime(new Date());
             studentTime.setFirstVipTime(new Date());
         }
         }
+
+        if (GoodTypeEnum.SVIP.equals(goodType) && null == studentTime.getFirstVipTime()) {
+            studentTime.setFirstSvipTime(new Date());
+        }
         if (GoodTypeEnum.PRACTICE.equals(goodType) && null == studentTime.getFirstPracticeTime()) {
         if (GoodTypeEnum.PRACTICE.equals(goodType) && null == studentTime.getFirstPracticeTime()) {
             studentTime.setFirstPracticeTime(new Date());
             studentTime.setFirstPracticeTime(new Date());
         }
         }

+ 310 - 30
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java

@@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
-import com.microsvc.toolkit.middleware.rtc.enums.EDeviceMessageType;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
@@ -21,11 +20,13 @@ import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.ImGroupType;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTagEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.TeacherTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.im.EImGroupMemberRoleType;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 import com.yonge.cooleshow.biz.dal.mapper.UserTenantBindRecordMapper;
 import com.yonge.cooleshow.biz.dal.mapper.UserTenantBindRecordMapper;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
@@ -48,10 +49,8 @@ import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantAlbumRefMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindHistoryMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindHistoryMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantUnbindRecordMapper;
-import com.yonge.cooleshow.biz.dal.queryInfo.TeacherQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
 import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
-import com.yonge.cooleshow.biz.dal.vo.MusicSheetUploadCountVo;
 import com.yonge.cooleshow.biz.dal.vo.MyFens;
 import com.yonge.cooleshow.biz.dal.vo.MyFens;
 import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
 import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
@@ -59,16 +58,16 @@ import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
 import com.yonge.cooleshow.biz.dal.wordfilter.WordFilter;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
-import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
 import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.ESettlementFrom;
 import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
 import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
 import com.yonge.cooleshow.common.enums.UserFirstTimeTypeEnum;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.base.util.StringUtil;
@@ -90,21 +89,12 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
 
 
 import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
 import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.redisson.api.RMap;
-import org.redisson.api.RedissonClient;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 
-import javax.annotation.Resource;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.Date;
@@ -112,11 +102,6 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Objects;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-import static com.yonge.cooleshow.biz.dal.constant.LiveRoomConstant.TEACHER_TEMP_LIVE_ROOM;
 
 
 @Service
 @Service
 public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {
 public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> implements TeacherService {
@@ -208,6 +193,8 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     @Autowired
     @Autowired
     private UserTenantBindRecordMapper userTenantBindRecordMapper;
     private UserTenantBindRecordMapper userTenantBindRecordMapper;
 
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
 
 
     @Override
     @Override
     public TeacherDao getDao() {
     public TeacherDao getDao() {
@@ -243,6 +230,14 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                 detail.setTenantName(tenantInfo == null ? "" : tenantInfo.getName());
                 detail.setTenantName(tenantInfo == null ? "" : tenantInfo.getName());
             }
             }
         }
         }
+
+        // 会员信息
+        detail.setUserVip(vipCardRecordService.userVipInfo(detail.getUserId(), ClientEnum.TEACHER));
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = vipCardRecordService.queryUserVipInfo(Collections.singletonList(userId), ClientEnum.TEACHER.getCode());
+        Map<Long, VipCardRecordWrapper.UserVipInfo> curVipMap = userVipInfos.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, Function.identity()));
+        VipCardRecordWrapper.UserVipInfo vipType = curVipMap.getOrDefault(userId, new VipCardRecordWrapper.UserVipInfo());
+        detail.setMembershipEndTime(vipType.getCurrentVipSvipEndTime());
+        detail.setVipType(vipType.getCurrentVipType());
         return detail;
         return detail;
     }
     }
 
 
@@ -250,6 +245,25 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     public IPage<TeacherVo> selectPage(IPage<TeacherVo> page, TeacherSearch search) {
     public IPage<TeacherVo> selectPage(IPage<TeacherVo> page, TeacherSearch search) {
         List<TeacherVo> teacherVos = baseMapper.selectPage(page, search);
         List<TeacherVo> teacherVos = baseMapper.selectPage(page, search);
 
 
+        for (TeacherVo record : teacherVos) {
+            EUserVipType vipType = record.getVipType();
+            if (EUserVipType.NORMAL.equals(vipType)) {
+                record.setMembershipEndTime(Optional.ofNullable(record.getVipEndTime()).orElse(record.getSvipEndTime()));
+            }
+            if (EUserVipType.SVIP.equals(vipType)) {
+                Date perSvipEndTime = record.getPerSvipEndTime();
+                if (perSvipEndTime != null) {
+                    // 永久会员
+                    record.setMembershipEndTime(null);
+                } else {
+                    record.setMembershipEndTime(record.getSvipEndTime());
+                }
+            }
+            if (EUserVipType.VIP.equals(vipType)) {
+                record.setMembershipEndTime(record.getVipEndTime());
+            }
+        }
+
         if (CollectionUtils.isEmpty(teacherVos)) {
         if (CollectionUtils.isEmpty(teacherVos)) {
             return page.setRecords(teacherVos);
             return page.setRecords(teacherVos);
         }
         }
@@ -304,12 +318,18 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             }).filter(Objects::nonNull).collect(Collectors.joining(","));
             }).filter(Objects::nonNull).collect(Collectors.joining(","));
             teacherVo.setSubjectName(subjectNames);
             teacherVo.setSubjectName(subjectNames);
         }
         }
+
+
+
+
         return page.setRecords(teacherVos);
         return page.setRecords(teacherVos);
     }
     }
 
 
     @Override
     @Override
     @Transactional(rollbackFor = Exception.class)
     @Transactional(rollbackFor = Exception.class)
     public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
     public HttpResponseResult<Boolean> submit(TeacherSubmitReq teacherSubmitReq) throws BizException {
+        // todo 暂时不上客服相关
+        teacherSubmitReq.setCustomerService(null);
         if (null == teacherSubmitReq.getUserId()) {
         if (null == teacherSubmitReq.getUserId()) {
 
 
             if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
             if (StringUtils.isNoneBlank(teacherSubmitReq.getPhone(), teacherSubmitReq.getCode())) {
@@ -351,6 +371,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
 
         teacherHomeVo.setDegreeDate(teacher.getDegreeDate());
         teacherHomeVo.setDegreeDate(teacher.getDegreeDate());
         teacherHomeVo.setTeacherDate(teacher.getTeacherDate());
         teacherHomeVo.setTeacherDate(teacher.getTeacherDate());
+        teacherHomeVo.setCustomerService(teacher.getCustomerService());
         //身份证号、手机号脱敏
         //身份证号、手机号脱敏
         teacherHomeVo.setIdCardNo(ValueUtil.fuzzyIdCard(teacherHomeVo.getIdCardNo()));
         teacherHomeVo.setIdCardNo(ValueUtil.fuzzyIdCard(teacherHomeVo.getIdCardNo()));
 //        teacherHomeVo.setPhone(ValueUtil.fuzzyMobile(teacherHomeVo.getPhone()));
 //        teacherHomeVo.setPhone(ValueUtil.fuzzyMobile(teacherHomeVo.getPhone()));
@@ -376,6 +397,11 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             }
             }
         }
         }
 
 
+        // 会员信息
+
+        teacherHomeVo.setUserVip(vipCardRecordService.userVipInfo(teacherHomeVo.getUserId(), ClientEnum.TEACHER));
+
+
         if (YesOrNoEnum.YES.equals(teacher.getMusicianFlag())) {
         if (YesOrNoEnum.YES.equals(teacher.getMusicianFlag())) {
             teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.PASS);
             teacherHomeVo.setMusicianAuthStatus(AuthStatusEnum.PASS);
         } else {
         } else {
@@ -599,18 +625,20 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             sendBindUnBindSMS(teacher.getUserId(), teacherSubmitReq.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, teacher.getTenantId());
             sendBindUnBindSMS(teacher.getUserId(), teacherSubmitReq.getPhone(), MessageTypeEnum.TEACHER_BIND_TENANT, teacher.getTenantId());
 
 
             //  与客服建立好友
             //  与客服建立好友
-            String customerService = customerServiceConfig.getCustomerService();
-            if (StringUtils.isNotBlank(customerService)) {
-                List<String> phones = Arrays.stream(customerService.split(",")).collect(Collectors.toList());
-                Random rand = new Random();
-                String mobile = phones.get(rand.nextInt(phones.size()));
-                SysUser friend = sysUserMapper.findUserByPhone(mobile);
-                if (friend != null) {
+            if (!Boolean.TRUE.equals(teacher.getCustomerService())) {
+                Teacher customerServiceTeacher = getCustomerServiceByFriendLeast();
+                if (customerServiceTeacher != null) {
                     imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
                     imUserFriendService.registerUserBindCustomerService(teacher.getUserId(),
-                            Collections.singletonList(friend.getId()), ClientEnum.TEACHER);
+                            Collections.singletonList(customerServiceTeacher.getUserId()), ClientEnum.TEACHER);
                 }
                 }
             }
             }
         } else {
         } else {
+            // 客服状态变更,移交好友信息
+            Boolean customerService = teacher.getCustomerService();
+            List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = new ArrayList<>();
+            if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
+                customerServiceSendMsg2User.addAll(transferFriend(teacher.getUserId(), true));
+            }
             // 如果机构解绑,更新机构ID为-1
             // 如果机构解绑,更新机构ID为-1
             if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
             if (Boolean.TRUE.equals(teacherSubmitReq.getBindTenant())) {
                 teacherSubmitReq.setTenantId(-1L);
                 teacherSubmitReq.setTenantId(-1L);
@@ -643,11 +671,200 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
             // 老师头像
             // 老师头像
             teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
             teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
             baseMapper.updateById(teacher);
             baseMapper.updateById(teacher);
+
+
+            // 交接后的客服发送消息
+            if (Boolean.TRUE.equals(customerService) && Boolean.FALSE.equals(teacherSubmitReq.getCustomerService())) {
+                String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
+                String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
+                for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
+                    imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getTeacherIds(),
+                            ClientEnum.TEACHER);
+                    imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),
+                            ClientEnum.STUDENT);
+                }
+            }
+
         }
         }
 
 
         return teacher;
         return teacher;
     }
     }
 
 
+    // 客服好友移交给其他客服
+    private List<TeacherWrapper.CustomerServiceSendMsg2User> transferFriend(Long userId, boolean saveGroupFriend) {
+        List<TeacherWrapper.CustomerServiceSendMsg2User> result = new ArrayList<>();
+        // 所有的好友
+        List<ImUserFriend> userFriendList = imUserFriendService.lambdaQuery()
+                .eq(ImUserFriend::getUserId, userId)
+                .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
+                .list();
+
+        // 其他客服
+        List<TeacherWrapper.TeacherFriend> customerServiceFriendNums = this.getBaseMapper().getCustomerServiceFriendNums();
+        customerServiceFriendNums.removeIf(n -> n.getTeacherId().equals(userId));
+        List<Long> customerIds = customerServiceFriendNums.stream().map(TeacherWrapper.TeacherFriend::getTeacherId).collect(Collectors.toList());
+        userFriendList.removeIf(n -> customerIds.contains(n.getFriendId()) && ClientEnum.TEACHER.equals(n.getFriendType()));
+        if (userFriendList.isEmpty()) { // 没有好友
+            return result;
+        }
+
+        List<ImUserFriend> removeFriendList = userFriendList;
+        if (saveGroupFriend) {
+            // 群里的好友保留
+            List<String> groupIdList = imGroupMemberService.lambdaQuery()
+                    .eq(ImGroupMember::getUserId, userId)
+                    .eq(ImGroupMember::getIsAdmin, true)
+                    .eq(ImGroupMember::getGroupRoleType, EImGroupMemberRoleType.Owner)
+                    .list()
+                    .stream()
+                    .map(ImGroupMember::getGroupId).collect(Collectors.toList());
+
+            List<Long> savedTeacherIdList = new ArrayList<>();
+            List<Long> savedStudentIdList = new ArrayList<>();
+
+            if (!groupIdList.isEmpty()) {
+                List<ImGroupMember> savedMemberList = imGroupMemberService.lambdaQuery()
+                        .in(ImGroupMember::getGroupId, groupIdList)
+                        .eq(ImGroupMember::getIsAdmin, false)
+                        .ne(ImGroupMember::getGroupRoleType, EImGroupMemberRoleType.Owner)
+                        .list();
+
+                savedTeacherIdList.addAll(savedMemberList.stream()
+                        .filter(n -> ImGroupMemberRoleType.TEACHER.equals(n.getRoleType()))
+                        .map(ImGroupMember::getUserId)
+                        .collect(Collectors.toList()));
+
+                savedStudentIdList.addAll(savedMemberList.stream()
+                        .filter(n -> ImGroupMemberRoleType.STUDENT.equals(n.getRoleType()))
+                        .map(ImGroupMember::getUserId)
+                        .collect(Collectors.toList()));
+            }
+
+            // 机构好友保留
+            Teacher teacher = this.getById(userId);
+            List<Long> tenantTeacherIds = new ArrayList<>();
+            List<Long> tenantStudentIds = new ArrayList<>();
+            if (teacher.getTenantId() > 0) {
+                List<Long> teacherIdList = userFriendList.stream().filter(n -> ClientEnum.TEACHER.equals(n.getFriendType())).map(ImUserFriend::getFriendId).collect(Collectors.toList());
+                List<Long> studentIdList = userFriendList.stream().filter(n -> ClientEnum.STUDENT.equals(n.getFriendType())).map(ImUserFriend::getFriendId).collect(Collectors.toList());
+                if (!teacherIdList.isEmpty()) {
+                    List<Long> tenantTeacherIdsTemp = this.lambdaQuery().in(Teacher::getUserId, teacherIdList)
+                            .eq(Teacher::getTenantId, teacher.getTenantId())
+                            .list()
+                            .stream().filter(n -> n.getTenantId() > 0).map(Teacher::getUserId).collect(Collectors.toList());
+                    tenantTeacherIds.addAll(tenantTeacherIdsTemp);
+                }
+                if (!studentIdList.isEmpty()) {
+                    List<Long> tenantStudentIdsTemp = studentService.lambdaQuery().in(Student::getUserId, studentIdList)
+                            .eq(Student::getTenantId, teacher.getTenantId())
+                            .list()
+                            .stream().filter(n -> n.getTenantId() > 0).map(Student::getUserId).collect(Collectors.toList());
+                    tenantStudentIds.addAll(tenantStudentIdsTemp);
+                }
+            }
+
+            // 删除的好友
+            removeFriendList = userFriendList.stream().filter(n -> {
+                if (ClientEnum.STUDENT.equals(n.getFriendType())) {
+                    if (tenantStudentIds.contains(n.getFriendId())) {
+                        return false;
+                    }
+                    return !savedStudentIdList.contains(n.getFriendId());
+                }
+                if (ClientEnum.TEACHER.equals(n.getFriendType())) {
+                    if (tenantTeacherIds.contains(n.getFriendId())) {
+                        return false;
+                    }
+                    return !savedTeacherIdList.contains(n.getFriendId());
+                }
+                return false;
+            }).collect(Collectors.toList());
+        }
+
+        // 删除好友
+        removeFriendList.stream().collect(Collectors.groupingBy(ImUserFriend::getFriendType)).forEach((client, friends) -> {
+            List<Long> friendIds = friends.stream().map(ImUserFriend::getFriendId).collect(Collectors.toList());
+            imUserFriendService.lambdaUpdate()
+                    .eq(ImUserFriend::getUserId, userId)
+                    .eq(ImUserFriend::getClientType, ClientEnum.TEACHER)
+                    .in(ImUserFriend::getFriendId, friendIds)
+                    .eq(ImUserFriend::getFriendType, client)
+                    .remove();
+
+            imUserFriendService.lambdaUpdate()
+                    .eq(ImUserFriend::getFriendId, userId)
+                    .eq(ImUserFriend::getFriendType, ClientEnum.TEACHER)
+                    .in(ImUserFriend::getUserId, friendIds)
+                    .eq(ImUserFriend::getClientType, client)
+                    .remove();
+        });
+
+        if (customerIds.isEmpty()) {
+            return result;
+        }
+        // 去除好友里面存在其他客服关系的好友,只有没有客服好友的好友,才需要与客服建立好友关系
+        List<ImUserFriend> teacherFriends = userFriendList.stream().filter(n -> ClientEnum.TEACHER.equals(n.getFriendType())).collect(Collectors.toList());
+        if (!teacherFriends.isEmpty()) {
+            String teacherFriendIds = teacherFriends.stream().map(n -> n.getFriendId().toString()).distinct().collect(Collectors.joining(","));
+            List<Long> existFriendIds = imUserFriendService.getDao().queryExistCustomerServiceFriend(teacherFriendIds, ClientEnum.TEACHER.getCode())
+                    .stream()
+                    .map(ImUserFriend::getUserId)
+                    .collect(Collectors.toList());
+            userFriendList.removeIf(n -> ClientEnum.TEACHER.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
+        }
+
+        List<ImUserFriend> studentFriends = userFriendList.stream().filter(n -> ClientEnum.STUDENT.equals(n.getFriendType())).collect(Collectors.toList());
+        if (!studentFriends.isEmpty()) {
+            String studentFriendIds = studentFriends.stream().map(n -> n.getFriendId().toString()).distinct().collect(Collectors.joining(","));
+            List<Long> existFriendIds = imUserFriendService.getDao().queryExistCustomerServiceFriend(studentFriendIds, ClientEnum.STUDENT.getCode())
+                    .stream()
+                    .map(ImUserFriend::getUserId)
+                    .collect(Collectors.toList());
+            userFriendList.removeIf(n -> ClientEnum.STUDENT.equals(n.getFriendType()) && existFriendIds.contains(n.getFriendId()));
+        }
+
+        if (userFriendList.isEmpty()) {
+            return result;
+        }
+
+        // 好友交接
+        Map<Long, Set<Long>> teacherFriendMap = new LinkedHashMap<>();
+        Map<Long, Set<Long>> studentFriendMap = new LinkedHashMap<>();
+        for (ImUserFriend imUserFriend : userFriendList) {
+            TeacherWrapper.TeacherFriend teacherFriend = customerServiceFriendNums.get(0);
+            if (ClientEnum.TEACHER.equals(imUserFriend.getFriendType())) {
+                Set<Long> set = teacherFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
+                set.add(imUserFriend.getFriendId());
+                teacherFriendMap.put(teacherFriend.getTeacherId(), set);
+            } else if (ClientEnum.STUDENT.equals(imUserFriend.getFriendType())) {
+                Set<Long> set = studentFriendMap.getOrDefault(teacherFriend.getTeacherId(), new HashSet<>());
+                set.add(imUserFriend.getFriendId());
+                studentFriendMap.put(teacherFriend.getTeacherId(), set);
+            }
+            teacherFriend.setFriendNums(teacherFriend.getFriendNums() + 1);
+            Collections.sort(customerServiceFriendNums);
+        }
+
+        teacherFriendMap.forEach((teacherId, teacherIds) -> {
+            imUserFriendService.saveUserTeacherFriend(teacherId, teacherIds);
+            // 发送消息
+            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
+            customerServiceSendMsg2User.setCustomerId(teacherId);
+            customerServiceSendMsg2User.getTeacherIds().addAll(teacherIds);
+            result.add(customerServiceSendMsg2User);
+//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(teacherIds), ClientEnum.TEACHER);
+        });
+        studentFriendMap.forEach((teacherId, studentIds) -> {
+            imUserFriendService.saveUserFriend(teacherId, studentIds);
+            TeacherWrapper.CustomerServiceSendMsg2User customerServiceSendMsg2User = new TeacherWrapper.CustomerServiceSendMsg2User();
+            customerServiceSendMsg2User.setCustomerId(teacherId);
+            customerServiceSendMsg2User.getTeacherIds().addAll(studentIds);
+            result.add(customerServiceSendMsg2User);
+//            imUserFriendService.sendCustomerServiceAddFriendMessage(teacherId, customerTitle, customerMessage, new ArrayList<>(studentIds), ClientEnum.STUDENT);
+        });
+        return result;
+    }
+
     /***
     /***
      * 封装用户信息
      * 封装用户信息
      * @author liweifan
      * @author liweifan
@@ -700,6 +917,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         teacher.setSettlementFrom(teacherSubmitReq.getSettlementFrom());
         teacher.setSettlementFrom(teacherSubmitReq.getSettlementFrom());
         teacher.setTenantId(teacherSubmitReq.getTenantId() == null ? -1L : teacherSubmitReq.getTenantId());
         teacher.setTenantId(teacherSubmitReq.getTenantId() == null ? -1L : teacherSubmitReq.getTenantId());
         teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
         teacher.setAvatar(Optional.ofNullable(teacherSubmitReq.getAvatar()).orElse(teacher.getAvatar()));
+        teacher.setCustomerService(teacherSubmitReq.getCustomerService());
         if (StringUtil.isEmpty(teacherSubmitReq.getTeacherType())) {
         if (StringUtil.isEmpty(teacherSubmitReq.getTeacherType())) {
             return teacher;
             return teacher;
         }
         }
@@ -912,6 +1130,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     public IPage<MyFens> queryMyFans(IPage<MyFens> page, Long teacherId) {
     public IPage<MyFens> queryMyFans(IPage<MyFens> page, Long teacherId) {
         List<MyFens> teacherVos = baseMapper.queryMyFans(page,
         List<MyFens> teacherVos = baseMapper.queryMyFans(page,
                 TeacherQueryInfo.FansQuery.builder().teacherId(teacherId).build());
                 TeacherQueryInfo.FansQuery.builder().teacherId(teacherId).build());
+        setVip(teacherVos);
         return page.setRecords(teacherVos);
         return page.setRecords(teacherVos);
     }
     }
 
 
@@ -926,6 +1145,7 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
     public IPage<MyFens> queryMyFans(IPage<MyFens> page, TeacherQueryInfo.FansQuery query) {
     public IPage<MyFens> queryMyFans(IPage<MyFens> page, TeacherQueryInfo.FansQuery query) {
 
 
         List<MyFens> teacherVos = baseMapper.queryMyFans(page, query);
         List<MyFens> teacherVos = baseMapper.queryMyFans(page, query);
+        setVip(teacherVos);
         return page.setRecords(teacherVos);
         return page.setRecords(teacherVos);
     }
     }
 
 
@@ -1033,7 +1253,6 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
 
             teacherInfo.setStudentNums(studentNumsMap.getOrDefault(teacherId, 0));
             teacherInfo.setStudentNums(studentNumsMap.getOrDefault(teacherId, 0));
         }
         }
-
         return teacherInfo;
         return teacherInfo;
     }
     }
 
 
@@ -1117,7 +1336,10 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
                 });
                 });
             }
             }
             // 删除好友关系
             // 删除好友关系
-            imUserFriendService.delStudentFriendByTenantId(teacher.getTenantId(), teacher.getUserId(), ClientEnum.TEACHER.getCode());
+            Boolean customerService = teacher.getCustomerService();
+            if (Boolean.FALSE.equals(customerService)) {
+                imUserFriendService.delStudentFriendByTenantId(teacher.getTenantId(), teacher.getUserId(), ClientEnum.TEACHER.getCode());
+            }
             addBindUnBindRecord(teacher.getUserId(), teacher.getTenantId(), false);
             addBindUnBindRecord(teacher.getUserId(), teacher.getTenantId(), false);
             SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
             SysUser sysUser = sysUserMapper.getByUserId(teacher.getUserId());
             sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_UNBIND_TENANT, teacher.getTenantId());
             sendBindUnBindSMS(teacher.getUserId(), sysUser.getPhone(), MessageTypeEnum.TEACHER_UNBIND_TENANT, teacher.getTenantId());
@@ -1250,4 +1472,62 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
         sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageType,
         sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, messageType,
                 receivers, null, 0, null, ClientEnum.SYSTEM.getCode(), tenantInfo.getName());
                 receivers, null, 0, null, ClientEnum.SYSTEM.getCode(), tenantInfo.getName());
     }
     }
+
+    private void setVip(List<MyFens> teacherVos) {
+        if (CollectionUtils.isEmpty(teacherVos)) {
+            return;
+        }
+        List<Long> studentIds = teacherVos.stream().map(n -> Long.valueOf(n.getUserId())).collect(Collectors.toList());
+        Map<Long, EUserVipType> vipMap = vipCardRecordService.queryUserVipInfo(studentIds, ClientEnum.STUDENT.getCode()).stream()
+                .collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId, VipCardRecordWrapper.UserVipInfo::getCurrentVipType));
+
+        for (MyFens teacherVo : teacherVos) {
+            EUserVipType vipType = vipMap.getOrDefault(Long.valueOf(teacherVo.getUserId()), EUserVipType.NORMAL);
+            teacherVo.setIsVip(EUserVipType.NORMAL.equals(vipType) ? YesOrNoEnum.NO : YesOrNoEnum.YES);
+            teacherVo.setVipType(vipType);
+        }
+    }
+
+    /**
+     * 获取学生好友最少的一个客服
+     * @return 客服
+     */
+    private Teacher getCustomerServiceByFriendLeast() {
+        return this.getBaseMapper().getCustomerServiceByFriendLeast();
+    }
+
+    @Override
+    public List<Teacher> getCustomerService() {
+        return this.lambdaQuery()
+                .eq(Teacher::getCustomerService, true)
+                .eq(Teacher::getLockFlag, false)
+                .list();
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void updateLock(SysUser sysUser, Long teacherId) {
+        Teacher teacher = this.getById(teacherId);
+        if (teacher == null) {
+            throw new BizException("无效的老师账号");
+        }
+
+        // todo 暂时不上,逻辑调整
+        // 冻结客服,移交好友给其他客服
+//        Boolean customerService = teacher.getCustomerService();
+        Boolean customerService = null;
+        if (UserLockFlag.NORMAL.equals(teacher.getLockFlag()) && Boolean.TRUE.equals(customerService)) {
+            List<TeacherWrapper.CustomerServiceSendMsg2User> customerServiceSendMsg2User = transferFriend(teacherId, false);
+            String customerMessage = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG);
+            String customerTitle = sysConfigService.findConfigValue(SysConfigConstant.CUSTOMER_SERVICE_ADD_MSG_TITLE);
+            for (TeacherWrapper.CustomerServiceSendMsg2User serviceSendMsg2User : customerServiceSendMsg2User) {
+                imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getTeacherIds(),
+                        ClientEnum.TEACHER);
+                imUserFriendService.sendCustomerServiceAddFriendMessage(serviceSendMsg2User.getCustomerId(), customerTitle, customerMessage, serviceSendMsg2User.getStudentIds(),
+                        ClientEnum.STUDENT);
+            }
+        }
+        teacher.setLockFlag(UserLockFlag.NORMAL.equals(teacher.getLockFlag()) ? UserLockFlag.LOCKED : UserLockFlag.NORMAL);
+        this.updateById(teacher);
+    }
 }
 }

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

@@ -296,11 +296,9 @@ public class TenantApplyRecordServiceImpl extends ServiceImpl<TenantApplyRecordM
         tenantApplyRecord.setVerifyUserId(verifyUserId);
         tenantApplyRecord.setVerifyUserId(verifyUserId);
         tenantApplyRecord.setReason(entry.getReason());
         tenantApplyRecord.setReason(entry.getReason());
         tenantApplyRecord.setBriefIntroduction(applyRecord.getBriefIntroduction());
         tenantApplyRecord.setBriefIntroduction(applyRecord.getBriefIntroduction());
-
-        applyRecord.setStatus(Boolean.TRUE.equals(ifPass) ? AuthStatusEnum.PASS : AuthStatusEnum.UNPASS);
-        applyRecord.setVerifyUserId(verifyUserId);
-        applyRecord.setReason(entry.getReason());
         if (ifPass == true){
         if (ifPass == true){
+            tenantApplyRecord.setStatus(AuthStatusEnum.PASS);
+
 
 
             //机构账户新增逻辑
             //机构账户新增逻辑
             TenantInfo tenantInfo = new TenantInfo();
             TenantInfo tenantInfo = new TenantInfo();
@@ -315,13 +313,19 @@ public class TenantApplyRecordServiceImpl extends ServiceImpl<TenantApplyRecordM
             tenantInfo.setBriefIntroduction(applyRecord.getBriefIntroduction());
             tenantInfo.setBriefIntroduction(applyRecord.getBriefIntroduction());
             if (tenantInfoService.add(tenantInfo)) {
             if (tenantInfoService.add(tenantInfo)) {
                 applyRecord.setUserId(tenantInfo.getUserId());
                 applyRecord.setUserId(tenantInfo.getUserId());
+                tenantApplyRecordMapper.updateById(applyRecord);
             }
             }
+            //更改当前记录的审核状态
+            tenantApplyRecordMapper.updateStatusById(id);
+        } else {
+            tenantApplyRecord.setStatus(AuthStatusEnum.UNPASS);
+            tenantApplyRecordMapper.updateUnpassStatusById(id);
         }
         }
-        tenantApplyRecordMapper.updateById(applyRecord);
-
 
 
+        String name = tenantEntryRecordMapper.selectName(verifyUserId);
+        tenantApplyRecord.setVerifyUserName(name);
 
 
-        TenantEntryRecord tenantEntryRecord = JSON.parseObject(JSON.toJSONString(applyRecord), TenantEntryRecord.class);
+        TenantEntryRecord tenantEntryRecord = JSON.parseObject(JSON.toJSONString(tenantApplyRecord), TenantEntryRecord.class);
          tenantEntryRecordMapper.insert(tenantEntryRecord);
          tenantEntryRecordMapper.insert(tenantEntryRecord);
 
 
 
 

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

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.dayaedu.cbs.common.enums.EClientType;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
 import com.yonge.cooleshow.biz.dal.dao.SubjectDao;
@@ -17,6 +18,7 @@ import com.yonge.cooleshow.biz.dal.entity.ImGroup;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.Teacher;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroup;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
 import com.yonge.cooleshow.biz.dal.entity.TenantGroupAlbum;
@@ -28,6 +30,7 @@ import com.yonge.cooleshow.biz.dal.mapper.TenantGroupAlbumMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 import com.yonge.cooleshow.biz.dal.mapper.TenantGroupMapper;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
 import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
 import com.yonge.cooleshow.biz.dal.service.TenantGroupService;
 import com.yonge.cooleshow.biz.dal.service.TenantGroupService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
 import com.yonge.cooleshow.biz.dal.service.im.ImGroupCoreService;
@@ -36,6 +39,7 @@ import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -71,6 +75,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
     private SysUserService sysUserService;
     private SysUserService sysUserService;
     @Autowired
     @Autowired
     private TenantGroupAlbumMapper tenantGroupAlbumMapper;
     private TenantGroupAlbumMapper tenantGroupAlbumMapper;
+    @Autowired
+    private SysConfigService sysConfigService;
 
 
     /**
     /**
      * 查询详情
      * 查询详情
@@ -162,6 +168,12 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
 
 
         this.save(entity);
         this.save(entity);
         if (adminId != null && Boolean.TRUE.equals(imGroupCreate)) {
         if (adminId != null && Boolean.TRUE.equals(imGroupCreate)) {
+            // 群成员数量限制校验
+            SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+            if (config != null && Integer.parseInt(config.getParamValue()) < (userIds.size() + 1)) {
+                throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+            }
+
             // 建群
             // 建群
             try {
             try {
                 ImGroupWrapper.ImGroup imGroup = new ImGroupWrapper.ImGroup();
                 ImGroupWrapper.ImGroup imGroup = new ImGroupWrapper.ImGroup();
@@ -231,6 +243,11 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
             ImGroup imGroup = imGroupService.getById(oldImGroupId);
             ImGroup imGroup = imGroupService.getById(oldImGroupId);
             // 群被删除过,并且需要重新建群
             // 群被删除过,并且需要重新建群
             if (imGroup == null) {
             if (imGroup == null) {
+                SysConfig config = sysConfigService.findByParamName(SysConfigConstant.GROUP_MEMBER_LIMIT);
+                if (config != null && Integer.parseInt(config.getParamValue()) < (tenantGroup.getUserIds().size() + 1)) {
+                    throw new BizException("群成员人数上限为:" + config.getParamValue() + "人");
+                }
+
                 String imGroupId = createImGroup(entity.getAdminId(), tenantGroup.getName());
                 String imGroupId = createImGroup(entity.getAdminId(), tenantGroup.getName());
                 entity.setImGroupId(imGroupId);
                 entity.setImGroupId(imGroupId);
 
 
@@ -431,8 +448,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
                     }
                     }
 
 
                     try {
                     try {
-                        imGroupCoreService.changeGroupOwner(imGroupId, String.valueOf(toTeacher),
-                                String.valueOf(teacherId));
+                        imGroupCoreService.changeGroupOwner(imGroupId, imGroupCoreService.getImUserId(toTeacher, ClientEnum.TEACHER),
+                                imGroupCoreService.getImUserId(teacherId, ClientEnum.TEACHER));
                         imGroupCoreService.groupQuit(teacherId, ClientEnum.TEACHER.getCode(),
                         imGroupCoreService.groupQuit(teacherId, ClientEnum.TEACHER.getCode(),
                                 imGroupId, true);
                                 imGroupId, true);
                         imGroupService.lambdaUpdate()
                         imGroupService.lambdaUpdate()
@@ -537,8 +554,8 @@ public class TenantGroupServiceImpl extends ServiceImpl<TenantGroupMapper, Tenan
 
 
         try {
         try {
             imGroupCoreService.changeGroupOwner(imGroupId,
             imGroupCoreService.changeGroupOwner(imGroupId,
-                    String.valueOf(newGroup.getAdminId()),
-                    String.valueOf(admin.getUserId()));
+                    imGroupCoreService.getImUserId(newGroup.getAdminId(), ClientEnum.TEACHER),
+                    imGroupCoreService.getImUserId(admin.getUserId(), ClientEnum.TEACHER));
             imGroupCoreService.groupQuit(admin.getUserId(), ClientEnum.TEACHER.getCode(), imGroupId, true);
             imGroupCoreService.groupQuit(admin.getUserId(), ClientEnum.TEACHER.getCode(), imGroupId, true);
             imGroupService.lambdaUpdate()
             imGroupService.lambdaUpdate()
                     .set(ImGroup::getCreateBy, newGroup.getAdminId())
                     .set(ImGroup::getCreateBy, newGroup.getAdminId())

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

@@ -103,6 +103,7 @@ public class UserAccountRecordServiceImpl extends ServiceImpl<UserAccountRecordD
         paramNames.add(AccountBizTypeEnum.ALBUM.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.ALBUM_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.VIP.getCode());
         paramNames.add(AccountBizTypeEnum.VIP.getCode());
+        paramNames.add(AccountBizTypeEnum.SVIP.getCode());
         paramNames.add(AccountBizTypeEnum.VIP_SHARE.getCode());
         paramNames.add(AccountBizTypeEnum.VIP_SHARE.getCode());
         List<UserAccountRecord> accountRecords = baseMapper.queryCanAccountByBizType(paramNames);
         List<UserAccountRecord> accountRecords = baseMapper.queryCanAccountByBizType(paramNames);
         for (UserAccountRecord accountRecord : accountRecords) {
         for (UserAccountRecord accountRecord : accountRecords) {
@@ -158,6 +159,10 @@ public class UserAccountRecordServiceImpl extends ServiceImpl<UserAccountRecordD
             bizIds.add(userOrderDetailVo.getBizId());
             bizIds.add(userOrderDetailVo.getBizId());
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP, bizIds));
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP, bizIds));
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP_SHARE, bizIds));
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP_SHARE, bizIds));
+        }else if (GoodTypeEnum.SVIP.equals(userOrderDetailVo.getGoodType())){
+            bizIds.add(userOrderDetailVo.getBizId());
+            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.SVIP, bizIds));
+            records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIP_SHARE, bizIds));
         }else if(GoodTypeEnum.VIDEO.equals(userOrderDetailVo.getGoodType())){
         }else if(GoodTypeEnum.VIDEO.equals(userOrderDetailVo.getGoodType())){
             bizIds.add(userOrderDetailVo.getBizId());
             bizIds.add(userOrderDetailVo.getBizId());
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIDEO, bizIds));
             records.addAll(baseMapper.selectRecordByOrderDetail(userOrderDetailVo.getOrderNo(),AccountBizTypeEnum.VIDEO, bizIds));

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

@@ -11,14 +11,19 @@ import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.StudentAttendance;
 import com.yonge.cooleshow.biz.dal.entity.StudentAttendance;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
 import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
 import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.enums.EUserVipType;
 import com.yonge.cooleshow.biz.dal.enums.StudentCourseEnum;
 import com.yonge.cooleshow.biz.dal.enums.StudentCourseEnum;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherBindingUserQueryInfo;
 import com.yonge.cooleshow.biz.dal.queryInfo.TeacherBindingUserQueryInfo;
 import com.yonge.cooleshow.biz.dal.service.StudentAttendanceService;
 import com.yonge.cooleshow.biz.dal.service.StudentAttendanceService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.UserBindingTeacherService;
 import com.yonge.cooleshow.biz.dal.service.UserBindingTeacherService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingCourseWrapper;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingCourseWrapper;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingTeacherWrapper;
 import com.yonge.cooleshow.biz.dal.vo.userBindingTeacher.UserBindingTeacherWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.exception.BizException;
@@ -34,7 +39,6 @@ import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.CollectionUtils;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 import java.util.Set;
 import java.util.Set;
@@ -64,6 +68,9 @@ public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeache
     @Autowired
     @Autowired
     private StudentAttendanceService studentAttendanceService;
     private StudentAttendanceService studentAttendanceService;
 
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
     @Override
     @Override
     public void unbindTask() {
     public void unbindTask() {
         String days = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_UNBIND_DAYS);
         String days = sysConfigService.findConfigValue(SysConfigConstant.PIANO_ROOM_UNBIND_DAYS);
@@ -105,10 +112,14 @@ public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeache
         // vip
         // vip
         List<Student> students = studentDao.selectBatchIds(studentIdList);
         List<Student> students = studentDao.selectBatchIds(studentIdList);
 
 
-        Map<Long, YesOrNoEnum> userIdVipMap = students.stream()
-                                                      .collect(Collectors.toMap(Student::getUserId,
-                                           student -> student.getMembershipEndTime() != null && student.getMembershipEndTime()
-                                           .compareTo(new Date()) > 0?YesOrNoEnum.YES:YesOrNoEnum.NO, (o, n) -> n));
+        List<VipCardRecordWrapper.UserVipInfo> studentVipInfoList = vipCardRecordService.queryUserVipInfo(studentIdList, ClientEnum.STUDENT.getCode());
+        Map<Long, EUserVipType> vipMap = studentVipInfoList.stream().collect(Collectors.toMap(VipCardRecordWrapper.UserVipInfo::getUserId,
+                VipCardRecordWrapper.UserVipInfo::getCurrentVipType));
+
+//        Map<Long, YesOrNoEnum> userIdVipMap = students.stream()
+//                                                      .collect(Collectors.toMap(Student::getUserId,
+//                                           student -> student.getMembershipEndTime() != null && student.getMembershipEndTime()
+//                                           .compareTo(new Date()) > 0?YesOrNoEnum.YES:YesOrNoEnum.NO, (o, n) -> n));
 
 
         // 声部
         // 声部
         List<Long> subjectIdList = new ArrayList<>();
         List<Long> subjectIdList = new ArrayList<>();
@@ -134,7 +145,9 @@ public class UserBindingTeacherServiceImpl extends ServiceImpl<UserBindingTeache
                                                                                             UserBindingTeacherWrapper.CourseNum::getStudentId));
                                                                                             UserBindingTeacherWrapper.CourseNum::getStudentId));
 
 
         for (UserBindingTeacherWrapper record : records) {
         for (UserBindingTeacherWrapper record : records) {
-            record.setIsVip(userIdVipMap.get(record.getUserId()));
+            EUserVipType vipType = vipMap.getOrDefault(record.getUserId(), EUserVipType.NORMAL);
+            record.setIsVip(EUserVipType.NORMAL.equals(vipType)?YesOrNoEnum.NO:YesOrNoEnum.YES);
+            record.setVipType(vipType);
             record.setSubjectName(userIdSubjectMap.getOrDefault(record.getUserId(), ""));
             record.setSubjectName(userIdSubjectMap.getOrDefault(record.getUserId(), ""));
 
 
             List<UserBindingTeacherWrapper.CourseNum> courseNums = userIdCourseStatusMap.get(record.getUserId());
             List<UserBindingTeacherWrapper.CourseNum> courseNums = userIdCourseStatusMap.get(record.getUserId());

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

@@ -8,6 +8,7 @@ import com.microsvc.toolkit.common.webportal.exception.BizException;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.EVipType;
 import com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper;
 import com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
@@ -69,6 +70,9 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
     @Autowired
     @Autowired
     private UserMusicMapper userMusicMapper;
     private UserMusicMapper userMusicMapper;
 
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
 
 
     /**
     /**
      * 查询详情
      * 查询详情
@@ -277,11 +281,16 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
         List<Long> studentIds = records.stream().filter(o -> o.getClientType() == ClientEnum.STUDENT).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
         List<Long> studentIds = records.stream().filter(o -> o.getClientType() == ClientEnum.STUDENT).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
 
 
         Map<Long, Student> studentMap = studentService.getMapByIds(studentIds);
         Map<Long, Student> studentMap = studentService.getMapByIds(studentIds);
+        // 学生vip状态
+        Map<Long, EVipType> studentVipTypeMap = vipCardRecordService.getVipTypeMapByUserIds(studentIds, ClientEnum.STUDENT);
 
 
 
 
         // 老师ID集合
         // 老师ID集合
         List<Long> teacherIds = records.stream().filter(o -> o.getClientType() == ClientEnum.TEACHER).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
         List<Long> teacherIds = records.stream().filter(o -> o.getClientType() == ClientEnum.TEACHER).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
 
 
+        // 老师vip状态
+        Map<Long, EVipType> teacherVipTypeMap = vipCardRecordService.getVipTypeMapByUserIds(teacherIds, ClientEnum.TEACHER);
+
         Map<Long, Teacher> teacherMap = teacherService.getMapByIds(teacherIds);
         Map<Long, Teacher> teacherMap = teacherService.getMapByIds(teacherIds);
         studentIds.addAll(teacherIds);
         studentIds.addAll(teacherIds);
         Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(studentIds);
         Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(studentIds);
@@ -301,7 +310,7 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
                 if (student != null) {
                 if (student != null) {
 
 
                     record.setSubjectId(student.getSubjectId());
                     record.setSubjectId(student.getSubjectId());
-                    record.setVipFlag(student.getMembershipEndTime() != null && student.getMembershipEndTime().after(new Date()));
+                    record.setVipType(studentVipTypeMap.getOrDefault(student.getUserId(),EVipType.NOT_VIP));
                 }
                 }
                 if (StringUtil.isEmpty(record.getAvatar())) {
                 if (StringUtil.isEmpty(record.getAvatar())) {
                     record.setAvatar(studentAvatar);
                     record.setAvatar(studentAvatar);
@@ -310,7 +319,7 @@ public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic
                 Teacher teacher = teacherMap.get(record.getUserId());
                 Teacher teacher = teacherMap.get(record.getUserId());
                 if (teacher != null) {
                 if (teacher != null) {
                     record.setSubjectId(teacher.getSubjectId());
                     record.setSubjectId(teacher.getSubjectId());
-                    record.setVipFlag(teacher.getMembershipEndTime() != null && teacher.getMembershipEndTime().after(new Date()));
+                    record.setVipType(teacherVipTypeMap.getOrDefault(teacher.getUserId(),EVipType.NOT_VIP));
                 }
                 }
                 if (StringUtil.isEmpty(record.getAvatar())) {
                 if (StringUtil.isEmpty(record.getAvatar())) {
                     record.setAvatar(teacherAvatar);
                     record.setAvatar(teacherAvatar);

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

@@ -27,6 +27,7 @@ import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
 import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.coupon.CouponOrderWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
@@ -157,6 +158,10 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     @Autowired
     @Autowired
     private TenantAlbumPurchaseService tenantAlbumPurchaseService;
     private TenantAlbumPurchaseService tenantAlbumPurchaseService;
 
 
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+
     //验证订单是否可以下单,获取订单金额信息
     //验证订单是否可以下单,获取订单金额信息
     private static final Map<GoodTypeEnum, Function<OrderReq.OrderReqInfo, HttpResponseResult<OrderCreateRes>>> orderCreate = new HashMap<>();
     private static final Map<GoodTypeEnum, Function<OrderReq.OrderReqInfo, HttpResponseResult<OrderCreateRes>>> orderCreate = new HashMap<>();
     //插入订单后执行
     //插入订单后执行
@@ -171,6 +176,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         /**********订单生成前******************/
         /**********订单生成前******************/
         //vip开通缴费
         //vip开通缴费
         orderCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
         orderCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
+        orderCreate.put(GoodTypeEnum.SVIP, memberPriceSettingsService::orderCreate);
         //直播课程购买
         //直播课程购买
         orderCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
         orderCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
         //陪练课购买
         //陪练课购买
@@ -195,6 +201,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         /**********订单完成后******************/
         /**********订单完成后******************/
         //vip开通缴费
         //vip开通缴费
         orderSuccess.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderSuccess);
         orderSuccess.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderSuccess);
+        orderSuccess.put(GoodTypeEnum.SVIP, memberPriceSettingsService::orderSuccess);
         //直播课程购买
         //直播课程购买
         orderSuccess.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseSuccess);
         orderSuccess.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseSuccess);
         //陪练课购买
         //陪练课购买
@@ -264,6 +271,11 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
     @Override
     @Override
     public UserOrderVo detailApp(UserOrder param) {
     public UserOrderVo detailApp(UserOrder param) {
         UserOrderVo userOrderVo = baseMapper.detailApp(param);
         UserOrderVo userOrderVo = baseMapper.detailApp(param);
+        userOrderDetail(userOrderVo);
+        return userOrderVo;
+    }
+
+    private void userOrderDetail( UserOrderVo userOrderVo) {
         if (null != userOrderVo) {
         if (null != userOrderVo) {
             userOrderVo.setFeeAmt(null);
             userOrderVo.setFeeAmt(null);
             userOrderVo.setPlantformFee(null);
             userOrderVo.setPlantformFee(null);
@@ -278,7 +290,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             CouponOrderWrapper couponOrderWrapper  = couponInfoService.queryUserOrderCouponInfo(userOrderVo.getUserId(),
             CouponOrderWrapper couponOrderWrapper  = couponInfoService.queryUserOrderCouponInfo(userOrderVo.getUserId(),
                     CouponInfoQuery.CouponOrderQuery.builder()
                     CouponInfoQuery.CouponOrderQuery.builder()
                             .clientType(userOrderVo.getOrderClient())
                             .clientType(userOrderVo.getOrderClient())
-                            .orderNo(param.getOrderNo())
+                            .orderNo(userOrderVo.getOrderNo())
                             .amount(userOrderVo.getExpectPrice().doubleValue())
                             .amount(userOrderVo.getExpectPrice().doubleValue())
                             .build());
                             .build());
             userOrderVo.setDiscountPrice(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
             userOrderVo.setDiscountPrice(BigDecimal.valueOf(couponOrderWrapper.getDiscountedPrices()));
@@ -290,12 +302,14 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 if (o.getGoodType().equals(GoodTypeEnum.TENANT_ALBUM) && userOrderVo.getOrderClient().equals(ClientEnum.TENANT)) {
                 if (o.getGoodType().equals(GoodTypeEnum.TENANT_ALBUM) && userOrderVo.getOrderClient().equals(ClientEnum.TENANT)) {
                     TenantAlbumPurchase albumPurchase = tenantAlbumPurchaseService.getByOrderNo(userOrderVo.getOrderNo());
                     TenantAlbumPurchase albumPurchase = tenantAlbumPurchaseService.getByOrderNo(userOrderVo.getOrderNo());
                     o.getBizInfo().setRecordId(albumPurchase.getId());
                     o.getBizInfo().setRecordId(albumPurchase.getId());
+                } else if (o.getGoodType().equals(GoodTypeEnum.SVIP)) {
+                    VipCardRecordWrapper.UserVip userVip = vipCardRecordService.userVipInfo(o.getUserId(), o.getOrderClient());
+                    o.setVipEndDays(userVip.getVipEndDays());
                 }
                 }
             });
             });
 
 
             userOrderVo.setOrderDetailList(userOrderDetailVos);
             userOrderVo.setOrderDetailList(userOrderDetailVos);
         }
         }
-        return userOrderVo;
     }
     }
 
 
     @Override
     @Override
@@ -535,6 +549,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                     break;
                     break;
                 }
                 }
                 case VIP:
                 case VIP:
+                case SVIP:
                 {
                 {
 
 
                     for (UserOrderDetailVo userOrderDetailVo : list) {
                     for (UserOrderDetailVo userOrderDetailVo : list) {
@@ -589,6 +604,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             info.setRecomUserId(orderReq.getRecomUserId());
             info.setRecomUserId(orderReq.getRecomUserId());
             info.setActivityId(orderReq.getActivityId());
             info.setActivityId(orderReq.getActivityId());
             info.setActualPrice(orderReq.getActualPrice());
             info.setActualPrice(orderReq.getActualPrice());
+            info.setOrderClient(orderReq.getOrderClient());
             HttpResponseResult<OrderCreateRes> createResult = createFunction.apply(info);
             HttpResponseResult<OrderCreateRes> createResult = createFunction.apply(info);
             OrderCreateRes createRes = createResult.getData();
             OrderCreateRes createRes = createResult.getData();
             if (!createResult.getStatus() || null == createRes || !createRes.getRes()) {
             if (!createResult.getStatus() || null == createRes || !createRes.getRes()) {
@@ -696,9 +712,15 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
 
 
     @Override
     @Override
     public HttpResponseResult<UserOrderVo> getPendingOrder(OrderSearch query) {
     public HttpResponseResult<UserOrderVo> getPendingOrder(OrderSearch query) {
+        if (query.getGoodType().equals(GoodTypeEnum.VIP.name()) || query.getGoodType().equals(GoodTypeEnum.SVIP.name())) {
+            query.setGoodType(Lists.newArrayList(GoodTypeEnum.VIP, GoodTypeEnum.SVIP).stream().map(GoodTypeEnum::name).collect(Collectors.joining(",")));
+        }
         UserOrderVo userOrderVo = baseMapper.getPendingOrder(query);
         UserOrderVo userOrderVo = baseMapper.getPendingOrder(query);
+
+
+        // SVIP和VIP同时只能存在一个待支付订单
         if (null != userOrderVo) {
         if (null != userOrderVo) {
-            userOrderVo.setOrderDetailList(orderDetailService.getOrderDetilListByOrderNo(userOrderVo.getOrderNo()));
+            userOrderDetail(userOrderVo);
 
 
 
 
             // 查询用户下单配置
             // 查询用户下单配置
@@ -922,6 +944,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
 
 
             UserOrderDetailVo orderDetail = new UserOrderDetailVo();
             UserOrderDetailVo orderDetail = new UserOrderDetailVo();
             orderDetail.setOrderNo(data.getOrderNo());
             orderDetail.setOrderNo(data.getOrderNo());
+            orderDetail.setBizJson(res.getBizJson());
             orderDetail.setOrderType(orderReq.getOrderType());
             orderDetail.setOrderType(orderReq.getOrderType());
             orderDetail.setSubOrderNo(data.getSubOrderNo());
             orderDetail.setSubOrderNo(data.getSubOrderNo());
             orderDetail.setMerchId(res.getMerchId());
             orderDetail.setMerchId(res.getMerchId());
@@ -1036,6 +1059,8 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_ACTI_REGIST);
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_ACTI_REGIST);
         } else if (GoodTypeEnum.ALBUM.equals(goodTypeEnum)) {
         } else if (GoodTypeEnum.ALBUM.equals(goodTypeEnum)) {
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_ALBUM);
             configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_ALBUM);
+        } else if (GoodTypeEnum.SVIP.equals(goodTypeEnum)) {
+            configValue = sysConfigService.findConfigValue(SysConfigConstant.GOOD_LOGO_SVIP);
         }
         }
         return configValue;
         return configValue;
     }
     }
@@ -1278,7 +1303,12 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
                 //入老师账户
                 //入老师账户
                 BigDecimal shareFee = platformFee.multiply(shareFeeRate).setScale(2, RoundingMode.HALF_UP);
                 BigDecimal shareFee = platformFee.multiply(shareFeeRate).setScale(2, RoundingMode.HALF_UP);
                 if (shareFee.compareTo(BigDecimal.ZERO) > 0) {
                 if (shareFee.compareTo(BigDecimal.ZERO) > 0) {
-                    AccountBizTypeEnum bizTypeEnum = AccountBizTypeEnum.valueOf(orderDetailVo.getGoodType().getCode() + "_SHARE");
+                    AccountBizTypeEnum bizTypeEnum;
+                    if (orderDetailVo.getGoodType() == GoodTypeEnum.SVIP || orderDetailVo.getGoodType() == GoodTypeEnum.VIP) {
+                        bizTypeEnum= AccountBizTypeEnum.VIP_SHARE;
+                    } else {
+                        bizTypeEnum = AccountBizTypeEnum.valueOf(orderDetailVo.getGoodType().getCode() + "_SHARE");
+                    }
                     if (null != bizTypeEnum) {
                     if (null != bizTypeEnum) {
                         //插入分润老师账户变更记录-分润老师预收
                         //插入分润老师账户变更记录-分润老师预收
                         HttpResponseResult<UserAccountRecord> recomRecordRes = userAccountService.accountRecord(
                         HttpResponseResult<UserAccountRecord> recomRecordRes = userAccountService.accountRecord(
@@ -1308,7 +1338,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         Calendar instance = Calendar.getInstance();
         Calendar instance = Calendar.getInstance();
         GoodTypeEnum goodType = orderDetailVo.getGoodType();
         GoodTypeEnum goodType = orderDetailVo.getGoodType();
 
 
-        if (GoodTypeEnum.VIP.equals(goodType)) {
+        if (GoodTypeEnum.VIP.equals(goodType) || GoodTypeEnum.SVIP.equals(goodType)) {
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.VIP_ACCOUNT_PERIOD)));
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.VIP_ACCOUNT_PERIOD)));
         } else if (GoodTypeEnum.PRACTICE.equals(goodType)) {
         } else if (GoodTypeEnum.PRACTICE.equals(goodType)) {
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.PRACTICE_ACCOUNT_PERIOD)));
             instance.add(Calendar.DAY_OF_MONTH, Integer.parseInt(sysConfigService.findConfigValue(SysConfigConstant.PRACTICE_ACCOUNT_PERIOD)));
@@ -1337,7 +1367,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      */
      */
     @Override
     @Override
     public BigDecimal getShareFreeByGoodType(GoodTypeEnum goodType, Long bizId) {
     public BigDecimal getShareFreeByGoodType(GoodTypeEnum goodType, Long bizId) {
-        if (GoodTypeEnum.VIP.equals(goodType)) {
+        if (GoodTypeEnum.VIP.equals(goodType) ||GoodTypeEnum.SVIP.equals(goodType)) {
             return getShareFreeByConfigName(SysConfigConstant.VIP_SHARE_FEE);
             return getShareFreeByConfigName(SysConfigConstant.VIP_SHARE_FEE);
         }
         }
         if (GoodTypeEnum.LIVE.equals(goodType)) {
         if (GoodTypeEnum.LIVE.equals(goodType)) {
@@ -1391,7 +1421,7 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
      */
      */
     private BigDecimal getPlatformFreeByGoodType(GoodTypeEnum goodType) {
     private BigDecimal getPlatformFreeByGoodType(GoodTypeEnum goodType) {
         //会员|琴房时长,平台全额收益
         //会员|琴房时长,平台全额收益
-        if (GoodTypeEnum.VIP.equals(goodType) || GoodTypeEnum.PIANO_ROOM.equals(goodType)
+        if (GoodTypeEnum.VIP.equals(goodType)|| GoodTypeEnum.SVIP.equals(goodType) || GoodTypeEnum.PIANO_ROOM.equals(goodType)
                 || GoodTypeEnum.ACTI_REGIST.equals(goodType)) {
                 || GoodTypeEnum.ACTI_REGIST.equals(goodType)) {
             return BigDecimal.ONE;
             return BigDecimal.ONE;
         }
         }

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

@@ -161,6 +161,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         /**********订单生成前 商品校验******************/
         /**********订单生成前 商品校验******************/
         //vip开通缴费
         //vip开通缴费
         orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
         orderGoodsCreate.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderCreate);
+        orderGoodsCreate.put(GoodTypeEnum.SVIP, memberPriceSettingsService::orderCreate);
         //直播课程购买
         //直播课程购买
         orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
         orderGoodsCreate.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourse);
         //陪练课购买
         //陪练课购买
@@ -198,6 +199,7 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
         paymentSuccess.put(GoodTypeEnum.VIDEO, paymentDivMemberRecordService::videoCourse);
         paymentSuccess.put(GoodTypeEnum.VIDEO, paymentDivMemberRecordService::videoCourse);
         paymentSuccess.put(GoodTypeEnum.ALBUM, paymentDivMemberRecordService::musicSheet);
         paymentSuccess.put(GoodTypeEnum.ALBUM, paymentDivMemberRecordService::musicSheet);
         paymentSuccess.put(GoodTypeEnum.VIP, paymentDivMemberRecordService::vip);
         paymentSuccess.put(GoodTypeEnum.VIP, paymentDivMemberRecordService::vip);
+        paymentSuccess.put(GoodTypeEnum.SVIP, paymentDivMemberRecordService::vip);
         paymentSuccess.put(GoodTypeEnum.ACTI_REGIST, paymentDivMemberRecordService::activity);
         paymentSuccess.put(GoodTypeEnum.ACTI_REGIST, paymentDivMemberRecordService::activity);
 
 
         /**********订单取消后******************/
         /**********订单取消后******************/
@@ -546,6 +548,10 @@ public class UserPaymentCoreServiceImpl implements UserPaymentCoreService {
                 orderGoodsCreate.get(item.getGoodType()).accept(item);
                 orderGoodsCreate.get(item.getGoodType()).accept(item);
                 UserOrderDetail userOrderDetail = item.getUserOrderDetail();
                 UserOrderDetail userOrderDetail = item.getUserOrderDetail();
                 orderDetails.add(userOrderDetail);
                 orderDetails.add(userOrderDetail);
+                couponAmount = userOrderDetail.getCouponAmount();
+                if (couponAmount == null) {
+                    couponAmount = BigDecimal.ZERO;
+                }
                 // 根据优惠券计算实际优惠金额
                 // 根据优惠券计算实际优惠金额
                 // 计算优惠券金额
                 // 计算优惠券金额
                 {
                 {

+ 43 - 43
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserTenantAlbumRecordServiceImpl.java

@@ -169,49 +169,49 @@ public class UserTenantAlbumRecordServiceImpl extends ServiceImpl<UserTenantAlbu
                     vo.setTenantImg(tenantInfo.getLogo());
                     vo.setTenantImg(tenantInfo.getLogo());
                 }
                 }
                 //查询机构专辑曲目表
                 //查询机构专辑曲目表
-                List<TenantAlbumMusic> tenantAlbumMusics = tenantAlbumMusicService.lambdaQuery()
-                        .eq(TenantAlbumMusic::getTenantAlbumId, i.getId())
-                        .eq(TenantAlbumMusic::getDelFlag, false)
-                        .list();
-
-                Map<SubjectTypeEnum, List<TenantAlbumMusic>> groupByType =
-                        tenantAlbumMusics.stream().collect(Collectors.groupingBy(TenantAlbumMusic::getSubjectType));
-
-                List<Long> musicSheetIdlist = tenantAlbumMusics.stream().map(next -> next.getMusicSheetId()).distinct().collect(Collectors.toList());
-
-                StudentMusicSheetSearch search = new StudentMusicSheetSearch();
-                search.setMusicSheetIdlist(musicSheetIdlist);
-                search.setPage(1);
-                search.setRows(9999);
-
-                IPage<MusicSheetVo> records = musicSheetService.selectStudentPage(PageUtil.getPage(search), search, ClientEnum.TENANT_STUDENT);
-
-                Map<Long, MusicSheetVo> idMsMap = records.getRecords().stream()
-                        .collect(Collectors.toMap(MusicSheet::getId, Function.identity()));
-
-                List<TenantAlbumWrapper.MusicSheetData> musicSheetData = vo.getMusicSheetData();
-
-                groupByType.forEach((key, value) -> {
-                    value.sort(Comparator.comparing(TenantAlbumMusic::getSortNumber));
-                    TenantAlbumWrapper.MusicSheetData sheetData = new TenantAlbumWrapper.MusicSheetData();
-                    sheetData.setSubjectType(key);
-                    List<TenantAlbumWrapper.TenantAlbumSheet> tenantAlbumSheets = value.stream().map(next -> {
-
-                        TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
-                        BeanUtils.copyProperties(next, tenantAlbumSheet);
-                        Long musicSheetId = tenantAlbumSheet.getMusicSheetId();
-                        MusicSheetVo musicSheet = idMsMap.getOrDefault(musicSheetId, new MusicSheetVo());
-                        tenantAlbumSheet.setMusicSheetName(musicSheet.getMusicSheetName());
-                        tenantAlbumSheet.setMusicTag(musicSheet.getMusicTag());
-                        tenantAlbumSheet.setComposer(musicSheet.getComposer());
-                        return tenantAlbumSheet;
-                    }).collect(Collectors.toList());
-
-
-                    sheetData.setTenantAlbumSheetList(tenantAlbumSheets);
-                    musicSheetData.add(sheetData);
-                    vo.setMusicSheetData(musicSheetData);
-                });
+//                List<TenantAlbumMusic> tenantAlbumMusics = tenantAlbumMusicService.lambdaQuery()
+//                        .eq(TenantAlbumMusic::getTenantAlbumId, i.getId())
+//                        .eq(TenantAlbumMusic::getDelFlag, false)
+//                        .list();
+//
+//                Map<SubjectTypeEnum, List<TenantAlbumMusic>> groupByType =
+//                        tenantAlbumMusics.stream().collect(Collectors.groupingBy(TenantAlbumMusic::getSubjectType));
+//
+//                List<Long> musicSheetIdlist = tenantAlbumMusics.stream().map(next -> next.getMusicSheetId()).distinct().collect(Collectors.toList());
+
+//                StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+//                search.setMusicSheetIdlist(musicSheetIdlist);
+//                search.setPage(1);
+//                search.setRows(9999);
+//
+//                IPage<MusicSheetVo> records = musicSheetService.selectStudentPage(PageUtil.getPage(search), search, ClientEnum.TENANT_STUDENT);
+//
+//                Map<Long, MusicSheetVo> idMsMap = records.getRecords().stream()
+//                        .collect(Collectors.toMap(MusicSheet::getId, Function.identity()));
+//
+//                List<TenantAlbumWrapper.MusicSheetData> musicSheetData = vo.getMusicSheetData();
+//
+//                groupByType.forEach((key, value) -> {
+//                    value.sort(Comparator.comparing(TenantAlbumMusic::getSortNumber));
+//                    TenantAlbumWrapper.MusicSheetData sheetData = new TenantAlbumWrapper.MusicSheetData();
+//                    sheetData.setSubjectType(key);
+//                    List<TenantAlbumWrapper.TenantAlbumSheet> tenantAlbumSheets = value.stream().map(next -> {
+//
+//                        TenantAlbumWrapper.TenantAlbumSheet tenantAlbumSheet = new TenantAlbumWrapper.TenantAlbumSheet();
+//                        BeanUtils.copyProperties(next, tenantAlbumSheet);
+//                        Long musicSheetId = tenantAlbumSheet.getMusicSheetId();
+//                        MusicSheetVo musicSheet = idMsMap.getOrDefault(musicSheetId, new MusicSheetVo());
+//                        tenantAlbumSheet.setMusicSheetName(musicSheet.getMusicSheetName());
+//                        tenantAlbumSheet.setMusicTag(musicSheet.getMusicTag());
+//                        tenantAlbumSheet.setComposer(musicSheet.getComposer());
+//                        return tenantAlbumSheet;
+//                    }).collect(Collectors.toList());
+//
+//
+//                    sheetData.setTenantAlbumSheetList(tenantAlbumSheets);
+//                    musicSheetData.add(sheetData);
+//                    vo.setMusicSheetData(musicSheetData);
+//                });
                 list.add(vo);
                 list.add(vo);
             });
             });
         }
         }

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

@@ -1,21 +1,26 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 
+import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.beust.jcommander.internal.Lists;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
 import com.yonge.cooleshow.biz.dal.dao.MemberPriceSettingsDao;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 import com.yonge.cooleshow.biz.dal.entity.ActivityReward;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.entity.MemberPriceSettings;
 import com.yonge.cooleshow.biz.dal.entity.Student;
 import com.yonge.cooleshow.biz.dal.entity.Student;
-import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
-import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
-import com.yonge.cooleshow.biz.dal.enums.PeriodEnum;
-import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.service.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.biz.dal.wrapper.VipCardRecordWrapper;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
+import com.yonge.toolset.utils.date.DateUtil;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.BeanUtils;
@@ -24,9 +29,13 @@ import org.springframework.stereotype.Service;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.entity.VipCardRecord;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
 import com.yonge.cooleshow.biz.dal.dao.VipCardRecordDao;
 import com.yonge.cooleshow.biz.dal.dao.VipCardRecordDao;
+import org.springframework.transaction.annotation.Transactional;
 
 
+import java.time.LocalDateTime;
+import java.time.ZoneId;
 import java.util.*;
 import java.util.*;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletableFuture;
+import java.util.stream.Collectors;
 
 
 
 
 @Service
 @Service
@@ -49,6 +58,10 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
     @Autowired
     @Autowired
     private UserOrderDetailService orderDetailService;
     private UserOrderDetailService orderDetailService;
 
 
+    @Autowired
+    private SysUserService sysUserService;
+
+
     @Override
     @Override
     public VipCardRecordVo detail(Long orderDetilId) {
     public VipCardRecordVo detail(Long orderDetilId) {
         return baseMapper.detail(orderDetilId, null);
         return baseMapper.detail(orderDetilId, null);
@@ -84,24 +97,24 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
             return null;
             return null;
         }
         }
         // 按时间区分 个数
         // 按时间区分 个数
-        Integer timeNum = 0;
+        Integer timeNum = orderDetailVo.getGoodNum();
         String periodType  = null;
         String periodType  = null;
 
 
         if (PeriodEnum.DAY.equals(detail.getPeriod())) {
         if (PeriodEnum.DAY.equals(detail.getPeriod())) {
-            timeNum = 1;
             periodType = PeriodEnum.DAY.getCode();
             periodType = PeriodEnum.DAY.getCode();
         } else if (PeriodEnum.MONTH.equals(detail.getPeriod())) {
         } else if (PeriodEnum.MONTH.equals(detail.getPeriod())) {
-            timeNum = 1;
             periodType = PeriodEnum.MONTH.getCode();
             periodType = PeriodEnum.MONTH.getCode();
         } else if (PeriodEnum.QUARTERLY.equals(detail.getPeriod())) {
         } else if (PeriodEnum.QUARTERLY.equals(detail.getPeriod())) {
-            timeNum = 3;
+            timeNum = timeNum*3;
             periodType = PeriodEnum.MONTH.getCode();
             periodType = PeriodEnum.MONTH.getCode();
         } else if (PeriodEnum.YEAR_HALF.equals(detail.getPeriod())) {
         } else if (PeriodEnum.YEAR_HALF.equals(detail.getPeriod())) {
-            timeNum = 6;
+            timeNum = timeNum*6;
             periodType = PeriodEnum.MONTH.getCode();
             periodType = PeriodEnum.MONTH.getCode();
         } else if (PeriodEnum.YEAR.equals(detail.getPeriod())) {
         } else if (PeriodEnum.YEAR.equals(detail.getPeriod())) {
-            timeNum = 1;
             periodType = PeriodEnum.YEAR.getCode();
             periodType = PeriodEnum.YEAR.getCode();
+        } else {
+            periodType = PeriodEnum.PERPETUAL.getCode();
+
         }
         }
 
 
         return getVipCardRecord(orderDetailVo.getUserId(),orderDetailVo.getOrderClient(),orderDetailVo.getOrderNo(),
         return getVipCardRecord(orderDetailVo.getUserId(),orderDetailVo.getOrderClient(),orderDetailVo.getOrderNo(),
@@ -118,23 +131,6 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
     @Override
     @Override
     public VipCardRecord getVipCardRecord(Long userId, ClientEnum client, String orderNo, String subOrderNo, String periodType,
     public VipCardRecord getVipCardRecord(Long userId, ClientEnum client, String orderNo, String subOrderNo, String periodType,
                                           Long memberPriceSettingsId, Integer timeNum, SourceTypeEnum sourceType, Long createBy, String reason) {
                                           Long memberPriceSettingsId, Integer timeNum, SourceTypeEnum sourceType, Long createBy, String reason) {
-        //修改用户会员时长
-        Date membershipEndTime = null;
-        if (client.equals(ClientEnum.STUDENT)) {
-            StudentVo studentVo = studentService.detail(userId);
-            if (null == studentVo) {
-                return null;
-            }
-            membershipEndTime = studentVo.getMembershipEndTime();
-        } else if (client.equals(ClientEnum.TEACHER)){
-            TeacherVo teacherVo = teacherService.detail(userId);
-            if (null == teacherVo) {
-                return null;
-            }
-            membershipEndTime = teacherVo.getMembershipEndTime();
-        } else {
-            return null;
-        }
 
 
         VipCardRecord vipCardRecord = new VipCardRecord();
         VipCardRecord vipCardRecord = new VipCardRecord();
         vipCardRecord.setUserId(userId);
         vipCardRecord.setUserId(userId);
@@ -149,11 +145,32 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         vipCardRecord.setCreateBy(createBy);
         vipCardRecord.setCreateBy(createBy);
         vipCardRecord.setReason(reason);
         vipCardRecord.setReason(reason);
 
 
-        if (null == membershipEndTime || membershipEndTime.before(new Date())) {
-            //没有会员、会员已过期 会员卡生效时间为当前时间
+        MemberPriceSettings memberPriceSettings = memberPriceSettingsDao.selectById(memberPriceSettingsId);
+        if (memberPriceSettings == null) {
+            return null;
+        }
+
+        VipCardRecordWrapper.UserVip userVip = userVipInfo(userId, client);
+        boolean flag= false;
+
+        if (userVip.getVipType() == EVipType.NOT_VIP) {
             vipCardRecord.setStartTime(new Date());
             vipCardRecord.setStartTime(new Date());
-        } else {
-            vipCardRecord.setStartTime(membershipEndTime);
+        } else if (userVip.getVipType() == EVipType.VIP && memberPriceSettings.getVipType() ==EVipType.VIP){
+            vipCardRecord.setStartTime(userVip.getVipEndDate());
+            flag= true;
+        } else if  (userVip.getVipType() == EVipType.VIP && memberPriceSettings.getVipType() ==EVipType.SVIP){
+            vipCardRecord.setStartTime(new Date());
+        }else if  (userVip.getVipType() == EVipType.SVIP && memberPriceSettings.getVipType() ==EVipType.VIP){
+            if (userVip.getVipEndDate() !=null) {
+                flag= true;
+                vipCardRecord.setStartTime(userVip.getVipEndDate());
+            } else {
+                flag= true;
+                vipCardRecord.setStartTime(userVip.getSvipEndDate());
+            }
+        }else if  (userVip.getVipType() == EVipType.SVIP && memberPriceSettings.getVipType() ==EVipType.SVIP){
+            flag= true;
+            vipCardRecord.setStartTime(userVip.getSvipEndDate());
         }
         }
         Calendar cal = Calendar.getInstance();
         Calendar cal = Calendar.getInstance();
         cal.setTime(vipCardRecord.getStartTime());
         cal.setTime(vipCardRecord.getStartTime());
@@ -165,7 +182,18 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         } else if (PeriodEnum.YEAR.getCode().equals(periodType)) {
         } else if (PeriodEnum.YEAR.getCode().equals(periodType)) {
             cal.add(Calendar.YEAR, timeNum);
             cal.add(Calendar.YEAR, timeNum);
         }
         }
+
         vipCardRecord.setEndTime(cal.getTime());
         vipCardRecord.setEndTime(cal.getTime());
+        if (flag) {
+            DateTime dateTime = DateTime.parse(DateUtil.format(vipCardRecord.getStartTime(), "yyyy-MM-dd"))
+                .plusDays(1)
+                .withHourOfDay(0)
+                .withMinuteOfHour(0)
+                .withSecondOfMinute(0)
+                .withMillisOfSecond(0);
+            vipCardRecord.setStartTime(dateTime.toDate());
+        }
+
         return vipCardRecord;
         return vipCardRecord;
     }
     }
 
 
@@ -179,15 +207,16 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         //提前三天提示
         //提前三天提示
         List<VipCardRecordVo> temporaryRecords = baseMapper.selectTemporaryRecord();
         List<VipCardRecordVo> temporaryRecords = baseMapper.selectTemporaryRecord();
         //标识
         //标识
-        Map<Long, Long> temporaryFlagMap = new HashMap<>();
+        Set<String> sendFlag = new HashSet<>();
         for (VipCardRecordVo record : temporaryRecords) {
         for (VipCardRecordVo record : temporaryRecords) {
-            if (null != temporaryFlagMap.get(record.getUserId())) {
+            String key = record.getUserId() + "_" + record.getVipType().getCode() + "_" + record.getClientType().getCode();
+            if (sendFlag.contains(key)) {
                 continue;
                 continue;
             }
             }
-            temporaryFlagMap.put(record.getUserId(), record.getUserId());
+            sendFlag.add(key);
             //发送消息
             //发送消息
             CompletableFuture.runAsync(() -> {
             CompletableFuture.runAsync(() -> {
-                temporary3DaysSend(record.getUserId(), record.getPhone(),record.getClientType());
+                temporary3DaysSend(record.getUserId(), record.getPhone(), record.getClientType(), record.getVipType());
             });
             });
             record.setMsgStatus(1);
             record.setMsgStatus(1);
             record.setUpdateTime(new Date());
             record.setUpdateTime(new Date());
@@ -200,16 +229,17 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
         //到期提示
         //到期提示
         List<VipCardRecordVo> expireRecords = baseMapper.selectExpireRecord();
         List<VipCardRecordVo> expireRecords = baseMapper.selectExpireRecord();
         //标识
         //标识
-        Map<Long, Long> expireFlagMap = new HashMap<>();
+        Set<String> expireSendFlag = new HashSet<>();
         for (VipCardRecordVo record : expireRecords) {
         for (VipCardRecordVo record : expireRecords) {
-            if (null != expireFlagMap.get(record.getUserId())) {
+            String key = record.getUserId() + "_" + record.getVipType().getCode() + "_" + record.getClientType().getCode();
+            if (expireSendFlag.contains(key)) {
                 continue;
                 continue;
             }
             }
-            expireFlagMap.put(record.getUserId(), record.getUserId());
+            expireSendFlag.add(key);
             //发送消息
             //发送消息
             //发送消息
             //发送消息
             CompletableFuture.runAsync(() -> {
             CompletableFuture.runAsync(() -> {
-                expireSend(record.getUserId(),record.getPhone(), record.getClientType());
+                expireSend(record.getUserId(),record.getPhone(), record.getClientType(), record.getVipType());
             });
             });
             record.setMsgStatus(2);
             record.setMsgStatus(2);
             record.setUpdateTime(new Date());
             record.setUpdateTime(new Date());
@@ -228,59 +258,712 @@ public class VipCardRecordServiceImpl extends ServiceImpl<VipCardRecordDao, VipC
 
 
     }
     }
 
 
+    /**
+     * 获取生效中的会员记录
+     * @param userId
+     * @param clientEnum
+     * @return
+     */
+    @Override
+    public List<VipCardRecord> getEfficientVipRecord(List<Long> userId, ClientEnum clientEnum) {
+        if (CollectionUtils.isEmpty(userId)) {
+            return new ArrayList<>();
+        }
+        return this.lambdaQuery()
+            .in(VipCardRecord::getUserId, userId)
+            .eq(VipCardRecord::getEfficientFlag, true)
+            .eq(VipCardRecord::getClientType, clientEnum.name())
+            .in(VipCardRecord::getVipType, Lists.newArrayList(EVipType.VIP,EVipType.SVIP))
+            .and(wrapper -> wrapper
+                .gt(VipCardRecord::getEndTime, new Date())
+            )
+            .list();
+    }
+
+    @Override
+    public VipCardRecordWrapper.UserVip UserVipInfo(Long userId, ClientEnum clientEnum) {
+        return userVipInfo(userId,clientEnum);
+    }
+    /**
+     * 用户会员信息
+     *
+     * @param userId
+     * @param clientEnum
+     * @return
+     */
+    @Override
+    public VipCardRecordWrapper.UserVip userVipInfo(Long userId, ClientEnum clientEnum) {
+        // 获取生效中的会员记录
+        VipCardRecordWrapper.UserVip userVip = new VipCardRecordWrapper.UserVip();
+        List<VipCardRecord> vipCardRecords = this.getEfficientVipRecord(Lists.newArrayList(userId),clientEnum);
+        if (CollectionUtils.isEmpty(vipCardRecords)) {
+            userVip.setVipType(EVipType.NOT_VIP);
+            // 判断有没有过期的会员类型
+            Integer vipCount = this.lambdaQuery()
+                .eq(VipCardRecord::getUserId, userId)
+                .eq(VipCardRecord::getEfficientFlag, true)
+                .eq(VipCardRecord::getVipType, EVipType.VIP)
+                .eq(VipCardRecord::getClientType, clientEnum.name())
+                .count();
+            Integer svipCount = this.lambdaQuery()
+                .eq(VipCardRecord::getUserId, userId)
+                .eq(VipCardRecord::getEfficientFlag, true)
+                .eq(VipCardRecord::getVipType, EVipType.SVIP)
+                .eq(VipCardRecord::getClientType, clientEnum.name())
+                .count();
+            if (vipCount>0&&svipCount>0) {
+                userVip.setExpireVipType(EVipType.ALL_VIP);
+            } else if (vipCount>0) {
+                userVip.setExpireVipType(EVipType.VIP);
+            } else if (svipCount>0) {
+                userVip.setExpireVipType(EVipType.SVIP);
+            }
+        } else {
+            // 存在没有结束时间的SVIP记录 永久SVIP
+            List<VipCardRecord> svipList = vipCardRecords.stream().filter(o -> o.getVipType() == EVipType.SVIP).collect(Collectors.toList());
+            Date svipEndDate = null;
+            if (CollectionUtils.isNotEmpty(svipList)) {
+                userVip.setVipType(EVipType.SVIP);
+
+                Optional<VipCardRecord> first = svipList.stream().filter(o ->o.getType()==PeriodEnum.PERPETUAL).findFirst();
+                if (first.isPresent()) {
+                    userVip.setVipType(EVipType.PERMANENT_SVIP);
+                }
+//                else {
+                Optional<VipCardRecord> max = svipList.stream().filter(o -> !PeriodEnum.PERPETUAL.equals(o.getType())).max(Comparator.comparing(VipCardRecord::getEndTime));
+                max.ifPresent(vipCardRecord -> userVip.setSvipEndDate(vipCardRecord.getEndTime()));
+//                }
+                Optional<VipCardRecord> max1 = svipList.stream().max(Comparator.comparing(VipCardRecord::getEndTime));
+                if (max1.isPresent()) {
+                    svipEndDate = max1.get().getEndTime();
+                }
+            } else {
+                Integer svipCount = this.lambdaQuery()
+                    .eq(VipCardRecord::getUserId, userId)
+                    .eq(VipCardRecord::getEfficientFlag, true)
+                    .eq(VipCardRecord::getVipType, EVipType.SVIP)
+                    .eq(VipCardRecord::getClientType, clientEnum.name())
+                    .count();
+                if (svipCount>0) {
+                    userVip.setExpireVipType(EVipType.SVIP);
+
+                }
+            }
+            // 过滤出VIP数据
+            List<VipCardRecord> vipList = vipCardRecords.stream().filter(o -> o.getVipType() == EVipType.VIP).collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(vipList)) {
+                if (userVip.getVipType() == null) {
+                    userVip.setVipType(EVipType.VIP);
+                }
+                Optional<VipCardRecord> max = vipList.stream().max(Comparator.comparing(VipCardRecord::getEndTime));
+                Optional<VipCardRecord> min = vipList.stream().min(Comparator.comparing(VipCardRecord::getStartTime));
+                max.ifPresent(vipCardRecord -> userVip.setVipEndDate(vipCardRecord.getEndTime()));
+                Date minDate = null;
+                if (min.isPresent()) {
+                    minDate = min.get().getStartTime();
+                }
+                // 设置VIP剩余天数
+                if (userVip.getVipEndDate() != null) {
+                    int num;
+                    if (svipEndDate != null && svipEndDate.after(new Date())) {
+                        num = DateUtil.daysBetween(svipEndDate, userVip.getVipEndDate());
+                    } else if (minDate != null && minDate.after(new Date())){
+                        num = DateUtil.daysBetween(minDate, userVip.getVipEndDate());
+                    } else {
+                        num = DateUtil.daysBetween(new Date(), userVip.getVipEndDate()) +1;
+                    }
+                    userVip.setVipEndDays(Math.max(num, 0));
+                }
+            } else {
+                Integer vipCount = this.lambdaQuery()
+                    .eq(VipCardRecord::getUserId, userId)
+                    .eq(VipCardRecord::getEfficientFlag, true)
+                    .eq(VipCardRecord::getVipType, EVipType.VIP)
+                    .eq(VipCardRecord::getClientType, clientEnum.name())
+                    .count();
+                if (vipCount>0) {
+                    userVip.setExpireVipType(EVipType.VIP);
+                }
+            }
+        }
+
+        if (userVip.getSvipEndDate() != null) {
+            int num = DateUtil.daysBetween(new Date(), userVip.getSvipEndDate()) +1;
+            userVip.setSvipEndDays(Math.max(num, 0));
+        }
+
+        // 设置会员过期时间
+        EVipType expireVipType = userVip.getExpireVipType();
+        List<VipCardRecordWrapper.UserVipInfo> userVipInfos = this.baseMapper.queryUserVipInfo(Collections.singletonList(userId), clientEnum.getCode());
+        if(!userVipInfos.isEmpty()){
+            VipCardRecordWrapper.UserVipInfo userVipInfo = userVipInfos.get(0);
+            Date date = new Date();
+            if (EVipType.VIP.equals(expireVipType) || EVipType.ALL_VIP.equals(expireVipType)) {
+                Date vipEndTime = userVipInfo.getVipEndTime();
+                if (vipEndTime != null && vipEndTime.before(date)) {
+                    double days = Math.ceil((date.getTime() - vipEndTime.getTime()) * 1.0D / (24 * 60 * 60 * 1000));
+                    userVip.setVipExpireDays((int) days);
+                }
+            }
+            if (EVipType.SVIP.equals(expireVipType) || EVipType.ALL_VIP.equals(expireVipType)) {
+                Date svipEndTime = userVipInfo.getSvipEndTime();
+                if (svipEndTime != null && svipEndTime.before(date)) {
+                    double days = Math.ceil((date.getTime() - svipEndTime.getTime()) * 1.0D / (24 * 60 * 60 * 1000));
+                    userVip.setSvipExpireDays((int) days);
+                }
+            }
+        }
+        return userVip;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    @Override
+    public void add(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
+        ClientEnum clientType = addVipCardRecord.getClientType();
+        if (!ClientEnum.STUDENT.equals(clientType) && !ClientEnum.TEACHER.equals(clientType)) {
+            throw new BizException("暂不支持非老师学生会员的增加或扣减");
+        }
+        if (EVipRecordStatus.DEDUCTION.equals(addVipCardRecord.getStatus())) {
+            VipCardRecord vipCardRecord = deductVip(addVipCardRecord);
+            vipCardRecord.setDisplayFlag(true);
+            this.save(vipCardRecord);
+        } else if (EVipRecordStatus.ADD.equals(addVipCardRecord.getStatus())) {
+            VipCardRecord addVip = addVip(addVipCardRecord);
+            this.save(addVip);
+            Integer vipDays = addVipCardRecord.getVipDays();
+            // 存在转换,先扣除,再添加
+            if (vipDays != null && vipDays > 0) {
+                VipCardRecordWrapper.AddVipCardRecord dedectRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecordWrapper.AddVipCardRecord.class);
+                dedectRecord.setStatus(EVipRecordStatus.DEDUCTION);
+                dedectRecord.setVipType(EVipType.VIP);
+                dedectRecord.setType(PeriodEnum.DAY);
+                dedectRecord.setTimes(vipDays);
+                dedectRecord.setReason("后台转换扣减");
+                deductVip(dedectRecord);
+
+                VipCardRecordWrapper.AddVipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecordWrapper.AddVipCardRecord.class);
+                addRecord.setStatus(EVipRecordStatus.ADD);
+                addRecord.setVipType(EVipType.SVIP);
+                addRecord.setType(PeriodEnum.DAY);
+                addRecord.setTimes(vipDays);
+                addRecord.setReason("购买SVIP升级原VIP");
+                VipCardRecord convertVip = addVip(addRecord);
+
+                convertVip.setDisplayFlag(true);
+                convertVip.setStatus(EVipRecordStatus.UPDATE);
+                convertVip.setSourceType(SourceTypeEnum.FREE_UPGRADE);
+                // 添加转换记录
+                this.save(convertVip);
+
+            }
+        }
+
+        if (Boolean.TRUE.equals(addVipCardRecord.getSendMsg())) {
+            sendAddVipMsg(addVipCardRecord);
+        }
+    }
+
+    @Override
+    public Map<Long, EVipType> getVipTypeMapByUserIds(List<Long> studentIds, ClientEnum client) {
+
+        List<VipCardRecord> vipCardRecords = this.getEfficientVipRecord(studentIds,client);
+
+        // 根据用户ID分组
+        Map<Long, List<VipCardRecord>> vipCardRecordMap = vipCardRecords.stream().collect(Collectors.groupingBy(VipCardRecord::getUserId));
+        Map<Long, EVipType> vipTypeMap = new HashMap<>();
+        vipCardRecordMap.forEach((k, v) -> {
+            List<VipCardRecord> svipList = v.stream().filter(o -> o.getVipType() == EVipType.SVIP).collect(Collectors.toList());
+            if (CollectionUtils.isNotEmpty(svipList)) {
+                vipTypeMap.put(k, EVipType.SVIP);
+            } else {
+                List<VipCardRecord> vipList = v.stream().filter(o -> o.getVipType() == EVipType.VIP).collect(Collectors.toList());
+                if (CollectionUtils.isNotEmpty(vipList)) {
+                    vipTypeMap.put(k, EVipType.VIP);
+                }
+            }
+        });
+        return vipTypeMap;
+    }
+
+    // 会员添加
+    @Override
+    public VipCardRecord addVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
+        List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
+                .eq(VipCardRecord::getClientType, addVipCardRecord.getClientType())
+                .eq(VipCardRecord::getUserId, addVipCardRecord.getUserId())
+                .ge(VipCardRecord::getEndTime, new Date())
+                .eq(VipCardRecord::getEfficientFlag, true)
+                .list()
+                .stream()
+//                .filter(n -> n.getEndTime() == null || n.getEndTime().after(new Date()))
+                .sorted(Comparator.comparing(VipCardRecord::getStartTime))
+                .collect(Collectors.toList());
+
+
+        EVipType addVipType = addVipCardRecord.getVipType();
+//        List<VipCardRecord> perpetualRecords = vipCardRecordList.stream()
+//                .filter(n -> n.getVipType().equals(addVipType) && PeriodEnum.PERPETUAL.equals(n.getType()))
+//                .collect(Collectors.toList());
+//        if (!perpetualRecords.isEmpty()) {
+//            throw new BizException("已经是永久会员");
+//        }
+
+        Date now = new Date();
+        long startTimeMills = now.getTime();
+        // 没有会员信息
+        if (vipCardRecordList.isEmpty()) {
+            PeriodEnum period = addVipCardRecord.getType();
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(now);
+            calendar.set(Calendar.HOUR_OF_DAY, 23);
+            calendar.set(Calendar.MINUTE, 59);
+            calendar.set(Calendar.SECOND, 59);
+            calendar.set(Calendar.MILLISECOND, 0);
+            Date endDate = plusDate(calendar.getTime(), period, Long.valueOf(addVipCardRecord.getTimes()));
+
+            VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
+            addRecord.setSourceType(addVipCardRecord.getSourceType() !=null?addVipCardRecord.getSourceType():SourceTypeEnum.BACKEND_GIVE);
+            addRecord.setStatus(EVipRecordStatus.ADD);
+            addRecord.setDisplayFlag(true);
+            addRecord.setEfficientFlag(true);
+            addRecord.setStartTime(now);
+            addRecord.setEndTime(endDate);
+            return addRecord;
+        }
+
+        // 找到插入数据的位置
+        int index = 0;
+        if (addVipType.equals(EVipType.VIP)) { // vip 放到最后
+            index = vipCardRecordList.size();
+            startTimeMills = vipCardRecordList.stream().map(VipCardRecord::getEndTime).max(Date::compareTo).get().getTime() + 1000L;
+        }
+        if (addVipType.equals(EVipType.SVIP)) { //放到VIP的前面
+            index = (int) vipCardRecordList.stream().filter(n -> EVipType.SVIP.equals(n.getVipType()) && !PeriodEnum.PERPETUAL.equals(n.getType())).count();
+            if (index > 0) {
+                startTimeMills = vipCardRecordList.stream().filter(n -> EVipType.SVIP.equals(n.getVipType()) && !PeriodEnum.PERPETUAL.equals(n.getType()))
+                        .map(VipCardRecord::getEndTime).max(Date::compareTo).get().getTime() + 1000;
+            }
+        }
+
+        VipCardRecord newRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
+        newRecord.setSourceType(addVipCardRecord.getSourceType() !=null?addVipCardRecord.getSourceType():SourceTypeEnum.BACKEND_GIVE);
+        newRecord.setStatus(EVipRecordStatus.ADD);
+        newRecord.setStartTime(new Date(startTimeMills));
+        if (index == 0) { // 当天剩余时间属于赠送
+            Calendar calendar = Calendar.getInstance();
+            calendar.setTime(new Date(startTimeMills));
+            calendar.set(Calendar.HOUR_OF_DAY, 23);
+            calendar.set(Calendar.MINUTE, 59);
+            calendar.set(Calendar.SECOND, 59);
+            calendar.set(Calendar.MILLISECOND, 0);
+            Date endDate = plusDate(calendar.getTime(), addVipCardRecord.getType(), Long.valueOf(addVipCardRecord.getTimes()));
+            newRecord.setEndTime(new Date(endDate.getTime()));
+        } else {
+            Date endDate = plusDate(new Date(startTimeMills - 1000), addVipCardRecord.getType(), Long.valueOf(addVipCardRecord.getTimes()));
+            newRecord.setEndTime(endDate);
+        }
+
+        newRecord.setDisplayFlag(true);
+        newRecord.setEfficientFlag(true);
+
+        // 平移时间
+//        long plusMills = newRecord.getEndTime().getTime() - startTimeMills;
+        long beforeEndTime = newRecord.getEndTime().getTime();
+        for (int i = 0; i < vipCardRecordList.size(); i++) {
+            VipCardRecord vipCardRecord = vipCardRecordList.get(i);
+            if (i >= index) {
+                VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                addRecord.setStatus(EVipRecordStatus.UPDATE);
+
+                addRecord.setStartTime(new Date(beforeEndTime + 1000));
+
+//                int days = (int) Math.ceil(plusMills * 1.0D / (24 * 60 * 60 * 1000));
+                Date endTime = plusDate(vipCardRecord.getEndTime(), addVipCardRecord.getType(), addVipCardRecord.getTimes());
+                addRecord.setEndTime(endTime);
+                addRecord.setDisplayFlag(false);
+                addRecord.setEfficientFlag(true);
+                save(addRecord);
+                Long refId = addRecord.getId();
+
+                VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                updateRecord.setEfficientFlag(false);
+                updateRecord.setRefId(refId);
+                updateById(updateRecord);
+                beforeEndTime = endTime.getTime();
+            }
+        }
+        return newRecord;
+    }
+
+    @Override
+    public List<VipCardRecordWrapper.UserVipInfo> queryUserVipInfo(List<Long> userIdList, String clientType) {
+        return baseMapper.queryUserVipInfo(userIdList, clientType);
+    }
+
+
+    // 会员扣减
+    private VipCardRecord deductVip(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
+
+        // 所有的会员重新生成
+        List<VipCardRecord> vipCardRecordList = this.lambdaQuery()
+                .eq(VipCardRecord::getClientType, addVipCardRecord.getClientType())
+                .eq(VipCardRecord::getUserId, addVipCardRecord.getUserId())
+                .ge(VipCardRecord::getEndTime, new Date())
+                .eq(VipCardRecord::getEfficientFlag, true)
+                .list()
+                .stream()
+                .sorted(Comparator.comparing(VipCardRecord::getStartTime))
+                .collect(Collectors.toList());
+
+        // 当前类型的VIP
+        PeriodEnum period = addVipCardRecord.getType();
+        // 扣减永久
+        if (PeriodEnum.PERPETUAL.equals(period)) {
+            addVipCardRecord.setTimes(1);
+            return deductedSVipPerpetual(addVipCardRecord, vipCardRecordList);
+        }
+
+        // 扣减非永久
+        List<VipCardRecord> collect = vipCardRecordList.stream()
+                .filter(n -> n.getVipType().equals(addVipCardRecord.getVipType()) && !PeriodEnum.PERPETUAL.equals(n.getType())).collect(Collectors.toList());
+        if (collect.isEmpty()) {
+            throw new BizException("剩余扣减数量不足");
+        }
+
+        Date now = new Date();
+        LocalDateTime maxEndTime = collect.stream().map(VipCardRecord::getEndTime).max(Comparator.naturalOrder()).get().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
+        // 扣减后的开始时间
+        LocalDateTime deductedStartTime;
+        switch (period) {
+            case DAY:
+                deductedStartTime = maxEndTime.minusDays(addVipCardRecord.getTimes());
+                break;
+            case MONTH:
+                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes());
+                break;
+            case QUARTERLY:
+                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 3L);
+                break;
+            case YEAR_HALF:
+                deductedStartTime = maxEndTime.minusMonths(addVipCardRecord.getTimes() * 6L);
+                break;
+            case YEAR:
+                deductedStartTime = maxEndTime.minusYears(addVipCardRecord.getTimes());
+                break;
+            default:
+                throw new BizException("不支持的扣减类型");
+        }
+        Date deductedStartDate =  Date.from(deductedStartTime.atZone(ZoneId.systemDefault()).toInstant());;
+
+        Date minStartTime = collect.stream().map(VipCardRecord::getStartTime).min(Comparator.naturalOrder()).get();
+        // 如果扣减的数量超过1天,则提示扣减数量不足
+        if (deductedStartDate.before(minStartTime)) {
+            double day = (minStartTime.getTime() - deductedStartDate.getTime()) * 1.0D / (24 * 60 * 60 * 1000);
+            if (day > 1.0D) {
+                if (addVipCardRecord.isOrderFlag()) {
+                    collect.stream().forEach(o->o.setEfficientFlag(false));
+
+                    this.updateBatchById(collect, 100);
+                    return null;
+                }
+
+                throw new BizException("剩余扣减数量不足");
+            }
+//            deductedStartDate = minStartTime;
+        }
+
+        // 重新计算会员时间,每一条记录置换成一条新的记录,时间区间重新计算
+        List<VipCardRecord> updateRecords = new ArrayList<>();
+        Long deductMills = null;
+        Long endDeductMills = null;
+
+        EVipType vipType = addVipCardRecord.getVipType();
+        boolean giveFlag = false; // 扣减后,剩余时间前移,第一条记录赠送当天的时间
+        for (VipCardRecord vipCardRecord : vipCardRecordList) {
+            Date startTime = vipCardRecord.getStartTime();
+            Date endTime = vipCardRecord.getEndTime();
+            if (endTime.before(deductedStartDate) || endTime.equals(deductedStartDate)) {
+                continue;
+            }
+            // 扣减vip,跳过SVIP
+            if (EVipType.VIP.equals(vipType) && EVipType.SVIP.equals(vipCardRecord.getVipType())) {
+                continue;
+            }
+
+            Long addId = null;
+            // 扣减到当前时间区间
+            if ((deductedStartDate.after(startTime) || deductedStartDate.equals(startTime)) && deductedStartDate.before(endTime)) {
+                if (deductedStartDate.after(now)) { // 还有剩余天数,不足一天,补充到当前全天
+                    VipCardRecord addRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                    addRecord.setId(null);
+                    addRecord.setDisplayFlag(false);
+                    addRecord.setEfficientFlag(true);
+                    addRecord.setEndTime(formatEnd(deductedStartDate));
+                    addRecord.setStatus(EVipRecordStatus.UPDATE);
+                    save(addRecord);
+                    addId = addRecord.getId();
+                }
+
+
+                deductMills = endTime.getTime() - deductedStartDate.getTime();
+                endDeductMills = endTime.getTime() - formatEnd(deductedStartDate).getTime();
+            } else {
+                if (vipCardRecord.getVipType().equals(vipType) && !PeriodEnum.PERPETUAL.equals(vipCardRecord.getType())) {
+                    deductMills = endTime.getTime() - deductedStartDate.getTime();
+                    endDeductMills = endTime.getTime() - formatEnd(deductedStartDate).getTime();
+                } else {
+                    // 有扣减,整体时间前移
+                    if (deductMills != null) {
+                        VipCardRecord newRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                        newRecord.setId(null);
+                        newRecord.setDisplayFlag(false);
+                        newRecord.setEfficientFlag(true);
+                        if (!giveFlag) {
+                            newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - deductMills));
+                            giveFlag = true;
+                        } else {
+                            newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - endDeductMills));
+                        }
+                        newRecord.setEndTime(new Date(newRecord.getEndTime().getTime() - endDeductMills));
+                        newRecord.setStatus(EVipRecordStatus.UPDATE);
+                        save(newRecord);
+                        addId = newRecord.getId();
+                    }
+                }
+            }
+
+            VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+            updateRecord.setEfficientFlag(false);
+            updateRecord.setRefId(addId);
+            updateRecords.add(updateRecord);
+        }
+
+        this.updateBatchById(updateRecords, 100);
+
+        VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
+        vipCardRecord.setEfficientFlag(false);
+        vipCardRecord.setStartTime(deductedStartDate);
+        vipCardRecord.setEndTime(Date.from(maxEndTime.atZone(ZoneId.systemDefault()).toInstant()));
+        vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
+        return vipCardRecord;
+    }
+
+    // 扣减永久SVIP会员
+    private VipCardRecord deductedSVipPerpetual(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord, List<VipCardRecord> vipCardRecordList) {
+        List<VipCardRecord> collect = vipCardRecordList.stream()
+                .filter(n -> n.getVipType().equals(addVipCardRecord.getVipType()) && n.getType().equals(PeriodEnum.PERPETUAL))
+                .collect(Collectors.toList());
+        if (collect.isEmpty()) {
+            throw new BizException("剩余扣减数量不足");
+        }
+
+
+        // 最后一个非永久SVIP的结束时间
+        Date lastUnPereutalDate = new Date();
+        Date lastEndUnPereutalDate = formatEnd(new Date());
+        Long deductMills = null;
+        Long endDeductMills = null;
+        boolean giveFlag = false;
+        for (VipCardRecord vipCardRecord : vipCardRecordList) {
+            if (EVipType.SVIP.equals(vipCardRecord.getVipType())) {
+                // 获取后续VIP向前平移的开始时间
+                if (!PeriodEnum.PERPETUAL.equals(vipCardRecord.getType())) {
+                    if (vipCardRecord.getEndTime().after(lastUnPereutalDate)) {
+                        lastUnPereutalDate = vipCardRecord.getEndTime();
+                        lastEndUnPereutalDate = vipCardRecord.getEndTime();
+                    }
+                    continue;
+                }
+                vipCardRecord.setEfficientFlag(false);
+                updateById(vipCardRecord);
+            } else {
+                VipCardRecord newRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                newRecord.setId(null);
+                newRecord.setDisplayFlag(false);
+                newRecord.setEfficientFlag(true);
+                if (vipCardRecord.getVipType().equals(addVipCardRecord.getVipType()) && !giveFlag) {
+                    deductMills = vipCardRecord.getStartTime().getTime() - lastUnPereutalDate.getTime();
+                    endDeductMills = vipCardRecord.getStartTime().getTime() - lastEndUnPereutalDate.getTime();
+                    newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - deductMills));
+                    giveFlag = true;
+                } else {
+                    endDeductMills = vipCardRecord.getStartTime().getTime() - lastEndUnPereutalDate.getTime();
+                    newRecord.setStartTime(new Date(newRecord.getStartTime().getTime() - endDeductMills));
+                }
+                newRecord.setEndTime(new Date(newRecord.getEndTime().getTime() - endDeductMills));
+                save(newRecord);
+                Long refId = newRecord.getId();
+
+                VipCardRecord updateRecord = JSON.parseObject(JSON.toJSONString(vipCardRecord), VipCardRecord.class);
+                updateRecord.setEfficientFlag(false);
+                updateRecord.setRefId(refId);
+                updateById(updateRecord);
+            }
+        }
+        VipCardRecord vipCardRecord = JSON.parseObject(JSON.toJSONString(addVipCardRecord), VipCardRecord.class);
+        vipCardRecord.setEfficientFlag(false);
+        vipCardRecord.setStatus(EVipRecordStatus.DEDUCTION);
+        return vipCardRecord;
+    }
+
+    private Date plusDate(Date start, PeriodEnum period, long times) {
+//        Calendar calendar = Calendar.getInstance();
+//        calendar.setTime(start);
+//        calendar.set(Calendar.HOUR_OF_DAY, 23);
+//        calendar.set(Calendar.MINUTE, 59);
+//        calendar.set(Calendar.SECOND, 59);
+//        calendar.set(Calendar.MILLISECOND, 0);
+        LocalDateTime localDateTimeMaxTime =  LocalDateTime.ofInstant(start.toInstant(),ZoneId.systemDefault());
+
+        LocalDateTime end;
+        switch (period) {
+            case DAY:
+                end = localDateTimeMaxTime.plusDays(times);
+                break;
+            case MONTH:
+                end = localDateTimeMaxTime.plusMonths(times);
+                break;
+            case QUARTERLY:
+                end = localDateTimeMaxTime.plusMonths(times * 3);
+                break;
+            case YEAR_HALF:
+                end = localDateTimeMaxTime.plusMonths(times * 6);
+                break;
+            case YEAR:
+                end = localDateTimeMaxTime.plusYears(times);
+                break;
+            case PERPETUAL:
+                // 永久默认给100年
+                end = localDateTimeMaxTime.plusYears(100);
+                break;
+            default:
+                throw new BizException("不支持的扣减类型");
+        }
+        return Date.from(end.atZone(ZoneId.systemDefault()).toInstant());
+    }
+
     // 发送会员到期3天消息推送
     // 发送会员到期3天消息推送
-    private void temporary3DaysSend(Long userId, String phone, ClientEnum clientType) {
+    private void temporary3DaysSend(Long userId, String phone, ClientEnum clientType, EVipType vipType) {
         Map<Long, String> receivers = new HashMap<>();
         Map<Long, String> receivers = new HashMap<>();
         receivers.put(userId, phone);
         receivers.put(userId, phone);
         // 判断是否是机构学生 机构学生推送走另一个
         // 判断是否是机构学生 机构学生推送走另一个
         if (clientType.equals(ClientEnum.STUDENT)) {
         if (clientType.equals(ClientEnum.STUDENT)) {
-        } else {
-            try {
-                String url = sysMessageService.selectConfigUrl(MessageTypeEnum.VIP_EXPIRE_THIRTY_DAY.getCode());
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.VIP_EXPIRE_THIRTY_DAY,
-                        receivers, null, 0, url, ClientEnum.STUDENT.getCode());
-            } catch (Exception e) {
-                log.error("会员到期3天极光消息推送异常,userId={}", userId);
+            Student student = studentService.getById(userId);
+            if (student == null || (student.getTenantId() != null && student.getTenantId() > 0 )) {
+                return;
             }
             }
+        }
+        try {
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
+                    EVipType.VIP.equals(vipType) ? MessageTypeEnum.VIP_EXPIRE_THIRTY_DAY : MessageTypeEnum.SVIP_EXPIRE_THIRTY_DAY
+                    , receivers, null, 0, null, clientType.getCode());
+        } catch (Exception e) {
+            log.error("会员到期3天极光消息推送异常,userId={}", userId);
+        }
 
 
-            try {
-                String url = sysMessageService.selectConfigUrl(MessageTypeEnum.SMS_VIP_EXPIRE_THIRTY_DAY.getCode());
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIP_EXPIRE_THIRTY_DAY,
-                        receivers, null, 0, null, ClientEnum.STUDENT.getCode(), url);
-            } catch (Exception e) {
-                log.error("会员到期3天短信消息推送异常,userId={}", userId);
-            }
+        try {
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
+                    EVipType.VIP.equals(vipType) ? MessageTypeEnum.SMS_VIP_EXPIRE_THIRTY_DAY : MessageTypeEnum.SMS_SVIP_EXPIRE_THIRTY_DAY
+                    , receivers, null, 0, null, clientType.getCode());
+        } catch (Exception e) {
+            log.error("会员到期3天短信消息推送异常,userId={}", userId);
         }
         }
     }
     }
 
 
     // 发送会员到期消息推送
     // 发送会员到期消息推送
-    private void expireSend(Long userId,String phone,ClientEnum userType) {
+    private void expireSend(Long userId,String phone,ClientEnum userType, EVipType vipType) {
         Map<Long, String> receivers = new HashMap<>();
         Map<Long, String> receivers = new HashMap<>();
         receivers.put(userId, phone);
         receivers.put(userId, phone);
         Student student = studentService.getById(userId);
         Student student = studentService.getById(userId);
         if (userType.equals(ClientEnum.STUDENT) && student != null  && student.getTenantId() != null && student.getTenantId() >0) {
         if (userType.equals(ClientEnum.STUDENT) && student != null  && student.getTenantId() != null && student.getTenantId() >0) {
-            try {
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TENANT_VIP_EXPIRE,
-                        receivers, null, 0, null, ClientEnum.TENANT_STUDENT.getCode());
-            } catch (Exception e) {
-                log.error("会员到期极光消息推送异常,userId={}", userId);
-            }
+//            try {
+//                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.TENANT_VIP_EXPIRE,
+//                        receivers, null, 0, null, ClientEnum.TENANT_STUDENT.getCode());
+//            } catch (Exception e) {
+//                log.error("会员到期极光消息推送异常,userId={}", userId);
+//            }
         } else {
         } else {
             try {
             try {
-                String url = sysMessageService.selectConfigUrl(MessageTypeEnum.VIP_EXPIRE.getCode());
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.VIP_EXPIRE,
-                        receivers, null, 0, url, userType.getCode());
+                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG,
+                        EVipType.VIP.equals(vipType) ? MessageTypeEnum.VIP_EXPIRE : MessageTypeEnum.SVIP_EXPIRE
+                        ,receivers, null, 0, null, userType.getCode());
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("会员到期3天极光消息推送异常,userId={}", userId);
                 log.error("会员到期3天极光消息推送异常,userId={}", userId);
             }
             }
 
 
             try {
             try {
-                String url = sysMessageService.selectConfigUrl(MessageTypeEnum.SMS_VIP_EXPIRE.getCode());
-                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_VIP_EXPIRE,
-                        receivers, null, 0, null, userType.getCode(), url);
+                sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS,
+                        EVipType.VIP.equals(vipType) ? MessageTypeEnum.SMS_VIP_EXPIRE : MessageTypeEnum.SMS_SVIP_EXPIRE,
+                        receivers, null, 0, null, userType.getCode());
             } catch (Exception e) {
             } catch (Exception e) {
                 log.error("会员到期3天短信消息推送异常,userId={}", userId);
                 log.error("会员到期3天短信消息推送异常,userId={}", userId);
             }
             }
         }
         }
     }
     }
+
+    // 添加、扣除会员发送推送
+    private void sendAddVipMsg(VipCardRecordWrapper.AddVipCardRecord addVipCardRecord) {
+        SysUser sysUser = sysUserService.getByUserId(addVipCardRecord.getUserId());
+        if (sysUser == null) {
+            return;
+        }
+        MessageTypeEnum messageTypeEnum;
+        EVipRecordStatus status = addVipCardRecord.getStatus();
+        EVipType vipType = addVipCardRecord.getVipType();
+        if (EVipRecordStatus.ADD.equals(status)) {
+            if (EVipType.VIP.equals(vipType)) {
+                messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_VIP;
+            }else {
+                PeriodEnum period = addVipCardRecord.getType();
+                if (PeriodEnum.PERPETUAL.equals(period)) {
+                    messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_PER_SVIP;
+                } else {
+                    messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_SVIP;
+                }
+            }
+        } else if (EVipRecordStatus.DEDUCTION.equals(status)) {
+            if (EVipType.VIP.equals(vipType)) {
+                messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_DUDECT_VIP;
+            }else {
+                PeriodEnum period = addVipCardRecord.getType();
+                if (PeriodEnum.PERPETUAL.equals(period)) {
+                    messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_DUDECT_PER_SVIP;
+                } else {
+                    messageTypeEnum = MessageTypeEnum.PLATFORM_ADD_DUDECT_SVIP;
+                }
+            }
+        } else {
+            throw new BizException("不支持类型");
+        }
+
+        Map<Long, String> receivers = new HashMap<>();
+        receivers.put(addVipCardRecord.getUserId(), sysUser.getPhone());
+
+        try {
+            sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, messageTypeEnum,
+                    receivers, null, 0, null, addVipCardRecord.getClientType().getCode(), String.valueOf(addVipCardRecord.getTimes()), addVipCardRecord.getType().getMsg(),
+                    addVipCardRecord.getReason());
+        } catch (Exception e) {
+            log.error("会员添加消息发送失败 : {}", e.getMessage());
+        }
+    }
+
+    private Date formatEnd(Date date) {
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(date);
+        c1.set(Calendar.HOUR_OF_DAY, 23);
+        c1.set(Calendar.MINUTE, 59);
+        c1.set(Calendar.SECOND, 59);
+        return c1.getTime();
+    }
+
+    private Date formatStart(Date date) {
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(date);
+        c1.set(Calendar.HOUR_OF_DAY, 0);
+        c1.set(Calendar.MINUTE, 0);
+        c1.set(Calendar.SECOND, 0);
+        c1.set(Calendar.MILLISECOND, 0);
+        return c1.getTime();
+    }
 }
 }

+ 2 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetDetailVo.java

@@ -28,6 +28,8 @@ public class MusicSheetDetailVo extends MusicSheet {
     @ApiModelProperty("是否能播放(0:否,1:是) 学生端进入小酷Ai判断 试用/完整 播放")
     @ApiModelProperty("是否能播放(0:否,1:是) 学生端进入小酷Ai判断 试用/完整 播放")
     private YesOrNoEnum play;
     private YesOrNoEnum play;
 
 
+    @ApiModelProperty("是否购买(0:否,1:是)")
+    private Boolean buyed = false;
 
 
     @ApiModelProperty("收藏0:否,1:是")
     @ApiModelProperty("收藏0:否,1:是")
     private YesOrNoEnum favorite;
     private YesOrNoEnum favorite;

Some files were not shown because too many files changed in this diff