Bläddra i källkod

fix单体服务布署

Eric 1 år sedan
förälder
incheckning
d256014b76
100 ändrade filer med 10745 tillägg och 0 borttagningar
  1. 27 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/HereWhiteController.java
  2. 260 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomController.java
  3. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomMemberController.java
  4. 7 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/config/AppConfigProperties.java
  5. 97 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ActivityController.java
  6. 100 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseCoursewareController.java
  7. 162 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseHomeworkController.java
  8. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CoursePlanController.java
  9. 69 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseRepliedController.java
  10. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseScheduleStudentMusicSheetController.java
  11. 27 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseScheduleStudentPaymentController.java
  12. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseScheduleTeacherSalaryController.java
  13. 116 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupController.java
  14. 79 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupMemberAuditController.java
  15. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupMemberController.java
  16. 74 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupNoticeController.java
  17. 102 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImUserFriendController.java
  18. 60 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MemberPriceSettingsController.java
  19. 207 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicAlbumController.java
  20. 401 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java
  21. 34 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicTagController.java
  22. 48 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/PianoRoomBuyRecordController.java
  23. 45 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/PianoRoomSettingsController.java
  24. 88 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SmsCodeController.java
  25. 44 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/StudentController.java
  26. 60 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SubjectController.java
  27. 82 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysConfigController.java
  28. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysImComplaintController.java
  29. 131 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java
  30. 84 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMusicCompareRecordController.java
  31. 41 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java
  32. 85 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysUserContractRecordController.java
  33. 28 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherAttendanceController.java
  34. 52 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherAuthEntryRecordController.java
  35. 49 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherAuthMusicianRecordController.java
  36. 283 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherController.java
  37. 153 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseGroupController.java
  38. 318 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseScheduleController.java
  39. 63 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherFreeTimeController.java
  40. 87 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherHomeController.java
  41. 128 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomController.java
  42. 56 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomVideoController.java
  43. 80 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UploadFileController.java
  44. 143 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserAccountController.java
  45. 119 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserBankCardController.java
  46. 339 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserOrderController.java
  47. 130 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserWithdrawalController.java
  48. 225 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupController.java
  49. 148 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupDetailController.java
  50. 61 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VipCardRecordController.java
  51. 108 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/coupon/CouponInfoController.java
  52. 199 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenShareController.java
  53. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/UserPaymentClient.java
  54. 110 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/UserWithdrawalClient.java
  55. 136 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/io/request/ActivityVo.java
  56. 137 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/io/request/CouponInfoVO.java
  57. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/task/TaskController.java
  58. 232 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/vo/UserPaymentOrderVo.java
  59. 155 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/IndexController.java
  60. 80 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/PaymentDivMemberRecordController.java
  61. 176 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java
  62. 128 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/SysAreaController.java
  63. 76 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/SysMusicCompareRecordController.java
  64. 24 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TaskController.java
  65. 155 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TeacherController.java
  66. 240 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantActivationCodeController.java
  67. 116 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java
  68. 116 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumPurchaseController.java
  69. 173 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantInfoController.java
  70. 84 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantUnbindRecordController.java
  71. 208 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java
  72. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/WechatMusicCompareRecordController.java
  73. 70 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenClient.java
  74. 150 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenStudentController.java
  75. 39 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenSubjectController.java
  76. 128 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenSysAreaController.java
  77. 52 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTeacherController.java
  78. 85 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTenantController.java
  79. 52 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/UserPaymentClient.java
  80. 168 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/SysAreaVo.java
  81. 39 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/SysUserWrapper.java
  82. 55 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/TenantInfoVo.java
  83. 52 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/StudentVo.java
  84. 99 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantActivationCodeVo.java
  85. 64 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantAlbumPurchaseVo.java
  86. 83 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantAlbumVo.java
  87. 76 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderDetailVo.java
  88. 232 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java
  89. 79 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseCoursewareController.java
  90. 109 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java
  91. 45 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/LiveRoomVideoController.java
  92. 124 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicAlbumController.java
  93. 253 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java
  94. 88 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/SmsCodeController.java
  95. 118 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/StudentController.java
  96. 74 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/SysConfigController.java
  97. 52 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherAuthEntryRecordController.java
  98. 49 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherAuthMusicianRecordController.java
  99. 153 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherController.java
  100. 63 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherFreeTimeController.java

+ 27 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/HereWhiteController.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.classroom.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.HereWhiteDto;
+import com.yonge.cooleshow.biz.dal.entity.ImNetworkHereWhite;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkHereWhiteService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.classroom:}/hereWhite")
+public class HereWhiteController extends BaseController {
+
+    @Autowired
+    private ImNetworkHereWhiteService hereWhiteService;
+
+    @ApiOperation("创建白板,默认全部采用零时白板")
+    @PostMapping(value = "create")
+    public HttpResponseResult<ImNetworkHereWhite> userAdd(@RequestBody HereWhiteDto hereWhiteDto) throws Exception {
+        return succeed(hereWhiteService.create(hereWhiteDto.getName(), hereWhiteDto.getUserNum(),hereWhiteDto.getCourseScheduleId()));
+    }
+}

+ 260 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomController.java

@@ -0,0 +1,260 @@
+package com.yonge.cooleshow.classroom.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.dto.ImChannelStateNotify;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkBaseDto;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkCustomMessage;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkDeviceControlDto;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkDisplayDataDto;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkMusicSheetDto;
+import com.yonge.cooleshow.biz.dal.dto.ImNetworkRoomResult;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.text.MessageFormat;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * 网络教室房间(room)表控制层
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:36
+ */
+@Api(tags = "网络教室房间")
+@RestController
+@RequestMapping("${app-config.url.classroom:}/room")
+public class ImNetworkRoomController extends BaseController {
+
+    private final static Logger log = LoggerFactory.getLogger(ImNetworkRoomController.class);
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImNetworkRoomService imNetworkRoomService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation("加入网络教室")
+    @PostMapping(value = "/join")
+    public HttpResponseResult<ImNetworkRoomResult> joinRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
+
+        // 设置请求客户端来源
+        if (Objects.isNull(imNetworkBaseDto.getClientType())) {
+            imNetworkBaseDto.setClientType(ClientEnum.STUDENT);
+        }
+
+        return imNetworkRoomService.joinRoom(Optional.ofNullable(imNetworkBaseDto)
+                .map(ImNetworkBaseDto::getRoomId)
+                .orElseThrow(()->new BizException("房间号不可为空")), imNetworkBaseDto.getClientType());
+    }
+
+//    @ApiOperation("加入网络教室状态回调")
+//    @PostMapping(value = "joinRoomSuccess", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+//    public HttpResponseResult joinRoomSuccess(Long courseScheduleId) throws Exception {
+//        imNetworkRoomService.joinRoomSuccess(courseScheduleId.toString(),UserRoleEnum.TEACHER);
+//        return succeed();
+//    }
+
+    @ApiOperation("加入网络教室状态回调")
+    @PostMapping(value = "joinRoomFailure")
+    public HttpResponseResult joinRoomFailure(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
+
+        // 设置请求客户端来源
+        if (Objects.isNull(imNetworkBaseDto.getClientType())) {
+            imNetworkBaseDto.setClientType(ClientEnum.STUDENT);
+        }
+
+        imNetworkRoomService.joinRoomFailure(Optional.ofNullable(imNetworkBaseDto)
+                .map(ImNetworkBaseDto::getRoomId)
+                .orElseThrow(()->new BizException("房间号不可为空")).toString(), imNetworkBaseDto.getClientType());
+        return succeed();
+    }
+
+    @PostMapping(value = "/statusSync")
+    @ApiOperation("加入网络教室状态回调")
+    public void statusSync(@RequestBody String body) throws Exception {
+        log.info("statusSync body: {}",body);
+        ImChannelStateNotify notify = JSONObject.parseObject(body, ImChannelStateNotify.class);
+
+        switch (notify.getEvent()) {
+            case 11:
+                //成员加入
+                imNetworkRoomService.joinRoomSuccess(notify.getRoomId(), notify.getUserId());
+                break;
+            case 12:
+                //成员退出
+                imNetworkRoomService.quitRoomSuccess(notify.getRoomId(), notify.getUserId());
+                break;
+        }
+    }
+
+    @ApiOperation("退出网络教室")
+    @PostMapping(value = "/leave")
+    public HttpResponseResult leaveRoom(@RequestBody ImNetworkBaseDto imNetworkBaseDto) throws Exception {
+
+        // 设置请求客户端来源
+        if (Objects.isNull(imNetworkBaseDto.getClientType())) {
+            imNetworkBaseDto.setClientType(ClientEnum.STUDENT);
+        }
+
+        // 用户ID
+        Long userId = sysUserService.getUserId();
+
+        // IM用户ID
+        String imUserId = String.valueOf(userId);
+        if (ClientEnum.STUDENT == imNetworkBaseDto.getClientType()) {
+            imUserId = MessageFormat.format("{0}:{1}", imUserId, ClientEnum.STUDENT.name());
+        }
+
+        imNetworkRoomService.quitRoomSuccess(Optional.ofNullable(imNetworkBaseDto)
+                .map(ImNetworkBaseDto::getRoomId)
+                .orElseThrow(()->new BizException("房间号不可为空")).toString(), imUserId);
+        return succeed();
+    }
+
+    @ApiOperation("控制学员节拍器")
+    @PostMapping(value = "/sendImPlayMidiMessage")
+    public HttpResponseResult sendImPlayMidiMessage(@RequestBody ImNetworkCustomMessage customMessage) throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(customMessage.getClientType())) {
+            customMessage.setClientType(ClientEnum.TEACHER);
+        }
+
+        imNetworkRoomService.sendImPlayMidiMessage(customMessage);
+        return succeed();
+    }
+
+    @ApiOperation("移动端用来渲染页面")
+    @PostMapping(value = "/display")
+    public HttpResponseResult display(@RequestBody ImNetworkDisplayDataDto displayData) throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(displayData.getClientType())) {
+            displayData.setClientType(ClientEnum.TEACHER);
+        }
+
+        imNetworkRoomService.display(displayData);
+        return succeed();
+    }
+
+    @ApiOperation(value = "批量控制学员设备开关")
+    @PostMapping(value = "/device/batchControl")
+    public Object batchControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(deviceControl.getClientType())) {
+            deviceControl.setClientType(ClientEnum.TEACHER);
+        }
+
+        imNetworkRoomService.batchControlDevice(deviceControl);
+        return succeed();
+    }
+
+    @ApiOperation(value = "控制学员设备开关")
+    @PostMapping(value = "/device/control")
+    public HttpResponseResult controlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
+            throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(deviceControl.getClientType())) {
+            deviceControl.setClientType(ClientEnum.TEACHER);
+        }
+
+        imNetworkRoomService.controlDevice(deviceControl);
+        return succeed();
+    }
+
+    @ApiOperation(value = "学员同意打开,麦克风、摄像头")
+    @PostMapping(value = "/device/approve")
+    public HttpResponseResult approveControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl) throws Exception {
+        deviceControl.setEnable(true);
+
+        // 设置客户端类型
+        if (Objects.isNull(deviceControl.getClientType())) {
+            deviceControl.setClientType(ClientEnum.STUDENT);
+        }
+
+        imNetworkRoomService.approveControlDevice(deviceControl);
+        return succeed();
+    }
+
+    @ApiOperation(value = "学员拒绝打开,麦克风、摄像头")
+    @PostMapping(value = "/device/reject")
+    public HttpResponseResult rejectControlDevice(@RequestBody ImNetworkDeviceControlDto deviceControl)
+            throws Exception {
+        deviceControl.setEnable(false);
+
+        // 设置客户端类型
+        if (Objects.isNull(deviceControl.getClientType())) {
+            deviceControl.setClientType(ClientEnum.STUDENT);
+        }
+
+        imNetworkRoomService.rejectControlDevice(deviceControl);
+        return succeed();
+    }
+
+    @ApiOperation(value = "学员设备状态同步")
+    @PostMapping(value = "/device/sync")
+    public Object deviceStatusSync(@RequestBody ImNetworkDeviceControlDto deviceControl)
+            throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(deviceControl.getClientType())) {
+            deviceControl.setClientType(ClientEnum.STUDENT);
+        }
+
+        imNetworkRoomService.deviceStatusSync(deviceControl);
+        return succeed();
+    }
+
+    @ApiOperation(value = "老师在网络教室选择完伴奏后、通知学员下载伴奏")
+    @PostMapping(value = "pushDownloadMusicSheetMsg")
+    public HttpResponseResult pushDownloadMusicSheetMsg(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(musicSheetDto.getClientType())) {
+            musicSheetDto.setClientType(ClientEnum.TEACHER);
+        }
+
+        imNetworkRoomService.pushDownloadMusicSheetMsg(musicSheetDto);
+        return succeed();
+    }
+
+    @ApiOperation(value = "学员伴奏下载状态回调")
+    @PostMapping(value = "musicSheetDownNotify")
+    public HttpResponseResult adjustMusicScore(@RequestBody ImNetworkMusicSheetDto musicSheetDto) throws Exception {
+
+        // 设置客户端类型
+        if (Objects.isNull(musicSheetDto.getClientType())) {
+            musicSheetDto.setClientType(ClientEnum.STUDENT);
+        }
+
+        imNetworkRoomService.musicSheetDownNotify(musicSheetDto);
+        return succeed();
+    }
+
+    @ApiOperation(value = "查询不在教室的学员")
+    @PostMapping(value = "/queryNoJoinStu")
+    public HttpResponseResult queryNoJoinStu(@RequestBody ImNetworkBaseDto imNetworkBaseDto){
+        return succeed(imNetworkRoomService.queryNoJoinStu(Optional.ofNullable(imNetworkBaseDto)
+                .map(ImNetworkBaseDto::getRoomId)
+                .orElseThrow(()->new BizException("房间号不可为空"))));
+    }
+}
+

+ 28 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/classroom/controller/ImNetworkRoomMemberController.java

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.classroom.controller;
+
+
+import com.yonge.cooleshow.biz.dal.service.ImNetworkRoomMemberService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 网络教室成员(ImNetworkRoomMember)表控制层
+ *
+ * @author zx
+ * @since 2022-03-30 16:36:37
+ */
+@Api(tags = "网络教室成员")
+@RestController
+@RequestMapping("${app-config.url.classroom:}/imNetworkRoomMember")
+public class ImNetworkRoomMemberController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImNetworkRoomMemberService imNetworkRoomMemberService;
+
+}
+

+ 7 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/config/AppConfigProperties.java

@@ -31,6 +31,9 @@ public class AppConfigProperties {
     @ApiModelProperty("网络教室")
     private String classroom;
 
+    @ApiModelProperty("机构端")
+    private String tenant;
+
     public String getAdmin() {
         return Optional.ofNullable(admin).orElse("");
     }
@@ -50,4 +53,8 @@ public class AppConfigProperties {
     public String getClassroom() {
         return Optional.ofNullable(classroom).orElse("");
     }
+
+    public String getTenant() {
+        return Optional.ofNullable(tenant).orElse("");
+    }
 }

+ 97 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ActivityController.java

@@ -0,0 +1,97 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.UserRewardQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.ActivityUserRewardService;
+import com.yonge.cooleshow.biz.dal.vo.CheckVo;
+import com.yonge.cooleshow.biz.dal.vo.activity.UserRewardWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.cooleshow.teacher.io.request.ActivityVo;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+
+@Api(tags = "活动接口")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/activity")
+public class ActivityController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(ActivityController.class);
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private ActivityUserRewardService activityUserRewardService;
+
+    @ApiOperation(value = "检查是否存在未领奖")
+    @GetMapping("/checkReceiveReward")
+    public HttpResponseResult<CheckVo> checkReceiveReward(){
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        Boolean b = activityUserRewardService.checkReceiveReward(user.getId(), ClientEnum.TEACHER);
+        YesOrNoEnum check = b?YesOrNoEnum.YES:YesOrNoEnum.NO;
+        CheckVo checkVo = new CheckVo();
+        checkVo.setCheck(check);
+
+        return succeed(checkVo);
+    }
+
+
+    @ApiOperation(value = "查看领奖列表")
+    @PostMapping("/receiveRewardList")
+    public HttpResponseResult<PageInfo<ActivityVo.ReceiveRewardList>> receiveRewardList(@RequestBody ActivityVo.ReceiveRewardQuery query){
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setClient(ClientEnum.TEACHER);
+        query.setReceive(YesOrNoEnum.NO);
+        query.setUserId(user.getId());
+
+        IPage<UserRewardWrapper> iPage = activityUserRewardService.receiveRewardList(PageUtil.getPage(query), UserRewardQueryInfo.from(query.jsonString()));
+
+        // 数据转换
+        List<ActivityVo.ReceiveRewardList> pageInfos = JSON.parseArray(JSON.toJSONString(iPage.getRecords()),
+                                                                       ActivityVo.ReceiveRewardList.class);
+
+        return succeed(PageUtil.getPageInfo(iPage,pageInfos));
+    }
+
+
+    @ApiOperation(value = "领取奖品")
+    @PostMapping("/receiveReward/{receiveRewardId}")
+    public HttpResponseResult<CheckVo> receiveReward(@PathVariable Long receiveRewardId){
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(activityUserRewardService.receiveReward(user.getId(), receiveRewardId));
+    }
+}
+

+ 100 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseCoursewareController.java

@@ -0,0 +1,100 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseCoursewareSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseCourseware;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseCoursewareService;
+import com.yonge.cooleshow.biz.dal.vo.CourseCoursewareVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+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.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseCourseware")
+@Api(value = "课件表", tags = "课件表")
+public class CourseCoursewareController extends BaseController {
+
+	@Autowired
+	private CourseCoursewareService courseCoursewareService;
+
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	/**
+	 * 查询分页
+	 */
+	@PostMapping("/page")
+	@ApiOperation(value = "查询分页", notes = "传入courseCoursewareSearch")
+	public HttpResponseResult<PageInfo<CourseCoursewareVo>> page(@RequestBody CourseCoursewareSearch query) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null) {
+			throw new BizException("请重新登录");
+		}
+		query.setClientType(ClientEnum.TEACHER);
+		query.setUserId(user.getId());
+		IPage<CourseCoursewareVo> pages = courseCoursewareService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+	/**
+	 * 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperation(value = "新增或修改", notes = "传入courseCourseware")
+	public HttpResponseResult<CourseCourseware> submit(@Valid @RequestBody CourseCourseware courseCourseware) {
+
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null) {
+			throw new BizException("请重新登录");
+		}
+
+		courseCourseware.setClientType(ClientEnum.TEACHER);
+		courseCourseware.setUserId(user.getId());
+		if (courseCourseware.getId() != null) {
+			courseCourseware.setUpdateTime(new Date());
+		} else {
+			courseCourseware.setUpdateTime(new Date());
+			courseCourseware.setCreateTime(new Date());
+		}
+		courseCourseware.setClientType(ClientEnum.TEACHER);
+		return succeed(courseCoursewareService.submit(courseCourseware));
+	}
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入id")
+	public HttpResponseResult remove(@PathVariable Long id ) {
+		return status(courseCoursewareService.removeById(id));
+	}
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "批量删除", notes = "传入id")
+	public HttpResponseResult remove(@RequestParam String ids ) {
+		return status(courseCoursewareService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

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

@@ -0,0 +1,162 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.CourseHomeworkReviewDto;
+import com.yonge.cooleshow.biz.dal.dto.CourseHomeworkSaveDto;
+import com.yonge.cooleshow.biz.dal.dto.CourseScheduleHomeworkSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseHomeworkService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.vo.CountVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeworkDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeworkVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleHomeworkVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description 老师课后作业相关接口
+ *
+ * @author liujunchi
+ * @date 2022-04-13
+ */
+@Api(tags = "老师课后作业相关接口")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/homework")
+public class CourseHomeworkController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+
+    @Autowired
+    private CourseHomeworkService courseHomeworkService;
+
+    @ApiOperation(value = "未布置的课后作业数量")
+    @GetMapping(value="/count")
+    public HttpResponseResult<CountVo> countTeacherNoDecorateHomework() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        HomeworkSearch homeworkSearch = new HomeworkSearch();
+        // 默认查当前老师,陪练课 课程状态为完成, 没有学生课程记录
+        homeworkSearch.setTeacherId(sysUser.getId());
+        homeworkSearch.setCourseStatus(CourseScheduleEnum.COMPLETE);
+        List<CourseScheduleEnum> list = new ArrayList<>();
+        list.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
+        list.add(CourseScheduleEnum.PRACTICE);
+        homeworkSearch.setCourseType(list);
+        homeworkSearch.setDecorate(YesOrNoEnum.NO);
+        Integer integer = courseScheduleService.countTeacherNoDecorateHomework(homeworkSearch);
+        CountVo countVo = new CountVo();
+        countVo.setCount(integer);
+        return succeed(countVo);
+    }
+
+    @ApiOperation(value = "首页-我的课程-课程详情(陪练课)-课后作业信息详情",notes = "传入课程编号ID")
+    @GetMapping(value = "/detail/{courseId}/{studentId}")
+    public HttpResponseResult<CourseHomeworkDetailVo> detail(@ApiParam(value = "课程编号ID", required = true)
+                                                                 @PathVariable("courseId") Long courseId,
+                                                             @PathVariable("studentId") Long studentId) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(courseId,sysUser);
+        if (info != null) return info;
+        return succeed(courseHomeworkService.getCourseHomeworkDetailByCourseId(courseId, studentId));
+    }
+
+
+    @ApiOperation(value = "首页-我的课程-课程详情(琴房)-课后作业列表",notes = "传入课程编号ID")
+    @PostMapping(value = "/detail/list")
+    public HttpResponseResult<CourseScheduleHomeworkVo> detail(@RequestBody @Valid CourseScheduleHomeworkSearch query) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(query.getCourseId(),sysUser);
+        if (info != null) return info;
+        return succeed(courseHomeworkService.getCourseHomeworkDetailByCourseId(query));
+    }
+
+    private HttpResponseResult checkCourseSchedule(Long courseId,SysUser sysUser) {
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (!courseScheduleService.checkTeacherCourseSchedule(sysUser.getId(), courseId)) {
+            return failed("老师只能看自己的课程详情");
+        }
+        return null;
+    }
+
+    @ApiOperation(value = "陪练课-布置作业", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/decorate", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Boolean> decorateCourseHomework(@Valid @RequestBody CourseHomeworkSaveDto saveDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(saveDto.getCourseScheduleId(),sysUser);
+        if (info != null) return info;
+        saveDto.setTeacherId(sysUser.getId());
+        return succeed(courseHomeworkService.decorateCourseHomework(saveDto));
+    }
+
+    @ApiOperation(value = "陪练课-作业点评", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/review", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Boolean> reviewCourseHomework(@Valid @RequestBody CourseHomeworkReviewDto reviewDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(reviewDto.getCourseScheduleId(),sysUser);
+        if (info != null) return info;
+        reviewDto.setTeacherId(sysUser.getId());
+        return succeed(courseHomeworkService.reviewCourseHomework(reviewDto));
+    }
+
+    @ApiOperation(value = "课后作业-列表", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/list", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<CourseHomeworkVo>> list(@Valid @RequestBody HomeworkSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (query.getDecorate() == null) {
+            return failed("布置状态不能为空");
+        }
+        query.setTeacherId(sysUser.getId());
+        query.setCourseStatus(CourseScheduleEnum.COMPLETE);
+        List<CourseScheduleEnum> list = new ArrayList<>();
+        list.add(CourseScheduleEnum.PIANO_ROOM_CLASS);
+        list.add(CourseScheduleEnum.PRACTICE);
+        query.setCourseType(list);
+
+        IPage<CourseHomeworkVo> page = courseHomeworkService.selectPage(PageUtil.getPage(query), query);
+        if (CollectionUtils.isNotEmpty(page.getRecords())) {
+
+            for (CourseHomeworkVo item : page.getRecords()) {
+
+                item.setImUserId(MessageFormat.format("{0}:{1}", String.valueOf(item.getStudentId()), ClientEnum.STUDENT.name()));
+            }
+        }
+
+        return succeed(PageUtil.pageInfo(page));
+    }
+
+
+}

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

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.service.CoursePlanService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 课程计划表(CoursePlan)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:11
+ */
+@Api(tags = "课程计划表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/coursePlan")
+public class CoursePlanController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CoursePlanService coursePlanService;
+
+}
+

+ 69 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseRepliedController.java

@@ -0,0 +1,69 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseRepliedService;
+import com.yonge.cooleshow.biz.dal.vo.CourseRepliedVo;
+import com.yonge.cooleshow.biz.dal.vo.MyRepliedVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/12
+ */
+@Api(tags = "陪练课")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseReplied")
+public class CourseRepliedController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private CourseRepliedService repliedService;
+
+    @ApiOperation(value = "首页-我的课程-课程详情-评价陪练课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/replied", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> replied(@Validated @RequestBody CourseScheduleReplied replied) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        replied.setCourseGroupType(CourseScheduleEnum.PRACTICE.getCode());
+        repliedService.replied(replied,sysUser);
+        return succeed();
+    }
+
+    @ApiOperation(value = "首页-我的课程-课程详情-查询陪练课评价")
+    @PostMapping(value = "/selectReplied")
+    public HttpResponseResult<CourseRepliedVo> selectReplied(@Validated @RequestBody CourseScheduleReplied replied) {
+        replied.setCourseGroupType(CourseScheduleEnum.PRACTICE.getCode());
+        return succeed(repliedService.selectReplied(replied));
+    }
+
+    @ApiOperation(value = "首页-我收到的评价")
+    @PostMapping(value = "/myReplied")
+    public HttpResponseResult<PageInfo<MyRepliedVo>> myReplied(@RequestBody MyCourseSearch search) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        search.setTeacherId(sysUser.getId());
+        IPage<MyRepliedVo> pages = repliedService.myReplied(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

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

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleStudentMusicSheetService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * (CourseScheduleStudentMusicSheet)表控制层
+ *
+ * @author zx
+ * @since 2022-04-02 15:56:00
+ */
+@Api(tags = "")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseScheduleStudentMusicSheet")
+public class CourseScheduleStudentMusicSheetController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseScheduleStudentMusicSheetService courseScheduleStudentMusicSheetService;
+
+}
+

+ 27 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/CourseScheduleStudentPaymentController.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleStudentPaymentService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 课程学生缴费表(CourseScheduleStudentPayment)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:12
+ */
+@Api(tags = "课程学生缴费表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseScheduleStudentPayment")
+public class CourseScheduleStudentPaymentController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseScheduleStudentPaymentService courseScheduleStudentPaymentService;
+
+}
+

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

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleTeacherSalaryService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 老师课酬表(CourseScheduleTeacherSalary)表控制层
+ *
+ * @author zx
+ * @since 2022-03-23 16:01:11
+ */
+@Api(tags = "老师课酬表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseScheduleTeacherSalary")
+public class CourseScheduleTeacherSalaryController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseScheduleTeacherSalaryService courseScheduleTeacherSalaryService;
+
+}
+

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

@@ -0,0 +1,116 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.ImGroupResultDto;
+import com.yonge.cooleshow.biz.dal.dto.ImGroupSearchDto;
+import com.yonge.cooleshow.biz.dal.entity.ImGroup;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.wrapper.im.ImGroupWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.utils.validator.ValidationKit;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 即时通讯群组(ImGroup)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:56
+ */
+@Api(tags = "即时通讯群组")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/imGroup")
+public class ImGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImGroupService imGroupService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation("创建群聊")
+    @PostMapping(value = "/create")
+    public HttpResponseResult create(@Valid @RequestBody ImGroupWrapper.ImGroup imGroup, BindingResult bindingResult) throws Exception {
+        ValidationKit.ignoreFields(bindingResult,"id");
+        imGroup.setCreateBy(sysUserService.getUserId());
+        imGroupService.create(imGroup);
+        return succeed();
+    }
+
+    @ApiOperation("添加群成员")
+    @PostMapping(value = "/addGroupMember")
+    public HttpResponseResult addGroupMember(@Valid @RequestBody ImGroupWrapper.ImGroup imGroup,
+                                             BindingResult bindingResult) throws Exception {
+        imGroupService.addGroupMember(imGroup.getId(), imGroup.getStudentIdList());
+        return succeed();
+    }
+
+    @ApiOperation("解散群聊")
+    @PostMapping(value = "/dismiss/{groupId}")
+    public HttpResponseResult dismiss(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        imGroupService.dismiss(groupId);
+        return succeed();
+    }
+
+    @ApiOperation("退出群聊")
+    @PostMapping(value = "/quit/{groupId}")
+    public HttpResponseResult quit(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        imGroupService.quit(groupId,sysUserService.getUserId(), ClientEnum.TEACHER);
+        return succeed();
+    }
+
+    @ApiOperation("获取群详情")
+    @PostMapping(value = "/getDetail/{groupId}")
+    public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        ImGroup group = imGroupService.getById(groupId);
+        if (group == null) {
+            return failed(HttpStatus.NO_CONTENT, "群组不存在");
+        }
+        return succeed(group);
+    }
+
+    @ApiOperation("群列表")
+    @PostMapping(value = "/queryAll")
+    public HttpResponseResult<List<ImGroup>> queryAll(@Valid @RequestBody ImGroupSearchDto imGroupSearchDto, BindingResult bindingResult) throws Exception {
+        ValidationKit.ignoreFields(bindingResult,"createUserId");
+        imGroupSearchDto.setUserId(sysUserService.getUserId());
+        // 设置群组成员身份
+        imGroupSearchDto.setRoleType(ImGroupMemberRoleType.TEACHER);
+
+        return succeed(imGroupService.queryAll(imGroupSearchDto));
+    }
+
+    @ApiOperation("修改群信息")
+    @PostMapping(value = "/update")
+    public HttpResponseResult<Boolean> update(@Valid @RequestBody ImGroup imGroup) throws Exception {
+        return succeed(imGroupService.updateById(imGroup));
+    }
+
+    @ApiOperation("获取指定用户的群列表")
+    @PostMapping(value = "/queryTeacherGroup")
+    public HttpResponseResult<List<ImGroupResultDto>> queryTeacherGroup(@RequestBody ImGroupSearchDto imGroupSearchDto) throws Exception {
+        if (StringUtils.isEmpty(imGroupSearchDto.getType())) {
+            imGroupSearchDto.setType("FAN");
+        }
+        return succeed(imGroupService.queryTeacherFun(imGroupSearchDto));
+    }
+}
+

+ 79 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupMemberAuditController.java

@@ -0,0 +1,79 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
+import com.yonge.cooleshow.biz.dal.enums.AuditStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
+import com.yonge.cooleshow.biz.dal.queryInfo.ImGroupMemberAuditQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * (ImGroupMemberAudit)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 17:18:51
+ */
+@Api(tags = "入群申请")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/imGroupMemberAudit")
+public class ImGroupMemberAuditController extends BaseController {
+
+    @Autowired
+    private ImGroupMemberAuditService imGroupMemberAuditService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation("申请入群")
+    @PostMapping(value = "/apply")
+    public HttpResponseResult apply(@Valid @RequestBody ImGroupMemberAudit imGroupMemberAudit) throws Exception {
+        imGroupMemberAudit.setRoleType(ImGroupMemberRoleType.TEACHER);
+        imGroupMemberAudit.setUserId(sysUserService.getUserId());
+        imGroupMemberAuditService.apply(imGroupMemberAudit, false);
+        return succeed();
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "auditIds", dataType = "String", value = "审核编号列表",required = true),
+            @ApiImplicitParam(name = "auditStatus", dataType = "String", value = "审核状态",required = true),
+            @ApiImplicitParam(name = "groupId", dataType = "String", value = "审核状态",required = true)
+    })
+    @ApiOperation("申请入群批量审核")
+    @PostMapping(value = "/applyAudit")
+    public HttpResponseResult applyAudit(@RequestBody Map<String,String> params) throws Exception {
+        if(Objects.isNull(params.get("auditIds"))
+                || Objects.isNull(params.get("auditStatus"))
+                || Objects.isNull(params.get("groupId"))){
+            throw new BizException("参数校验失败");
+        }
+        imGroupMemberAuditService.applyAudit(params.get("auditIds"),
+                AuditStatusEnum.valueOf(params.get("auditStatus")),
+                params.get("groupId"));
+        return succeed();
+    }
+
+    @ApiOperation("申请入群列表")
+    @PostMapping(value = "/queryAll")
+    public HttpResponseResult<List<ImGroupMemberAudit>> queryAll(@Valid @RequestBody ImGroupMemberAuditQueryInfo queryInfo){
+        return succeed(imGroupMemberAuditService.queryAll(queryInfo));
+    }
+
+}
+

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupMemberController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
+import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 即时通讯群组(ImGroupMember)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:56
+ */
+@Api(tags = "即时通讯群组联系人")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/imGroupMember")
+public class ImGroupMemberController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImGroupMemberService imGroupMemberService;
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "groupId", dataType = "String", value = "群编号",required = true),
+            @ApiImplicitParam(name = "userId", dataType = "Long", value = "用户编号",required = true),
+    })
+    @ApiOperation("获取好友详情")
+    @PostMapping(value = "/getUserDetail")
+    public HttpResponseResult<ImUserFriendVO.ImGroupMember> getUserDetail(@RequestBody Map<String,Object> params) {
+        if(Objects.isNull(params.get("groupId")) || Objects.isNull(params.get("userId"))){
+            throw new BizException("参数校验失败");
+        }
+
+        String userId = MapUtils.getString(params, "userId", "");
+
+        String ret = userId.split(":")[0];
+        if (!ret.matches(MK.EXP_INT)) {
+            return failed("无效的用户ID");
+        }
+
+        ImGroupMember groupMember = imGroupMemberService.getUserDetail(userId, params.get("groupId").toString());
+        if (Objects.isNull(groupMember)) {
+            return failed("用户无当前群组权限");
+        }
+
+        return succeed(ImUserFriendVO.ImGroupMember.from(JSON.toJSONString(groupMember)));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "search", dataType = "String", value = "根据用户编号、昵称模糊查询"),
+            @ApiImplicitParam(name = "groupId", dataType = "Long", value = "群编号")
+    })
+    @ApiOperation("获取群成员列表")
+    @PostMapping(value = "/queryAll")
+    public HttpResponseResult<List<ImGroupMember>> queryAll(@RequestBody Map<String,Object> params) throws Exception {
+        if(Objects.isNull(params.get("groupId"))){
+            throw new BizException("参数校验失败");
+        }
+
+        // 群组成员信息
+        List<ImGroupMember> groupMembers = imGroupMemberService.findChatGroupAllMemberInfo(params);
+
+        /*Object search = params.get("search");
+        List<ImGroupMember> iPage = imGroupMemberService.list(new QueryWrapper<ImGroupMember>().lambda()
+                .and(Objects.nonNull(search) && StringUtils.isNotEmpty(search.toString()),e->e.
+                        eq(ImGroupMember::getUserId, search).or()
+                        .like(ImGroupMember::getNickname, search))
+                .eq(ImGroupMember::getGroupId,params.get("groupId")).orderByDesc(ImGroupMember::getId));*/
+        return succeed(groupMembers);
+    }
+}
+

+ 74 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImGroupNoticeController.java

@@ -0,0 +1,74 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.ImGroupNoticeDto;
+import com.yonge.cooleshow.biz.dal.entity.ImGroupNotice;
+import com.yonge.cooleshow.biz.dal.service.ImGroupNoticeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.utils.validator.ValidationKit;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Map;
+
+/**
+ * 群公告(ImGroupNotice)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:58
+ */
+@Api(tags = "群公告")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/imGroupNotice")
+public class ImGroupNoticeController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImGroupNoticeService imGroupNoticeService;
+
+    @ApiOperation("新增群公告")
+    @PostMapping(value = "/create")
+    public HttpResponseResult create(@Valid @RequestBody ImGroupNotice imGroupNotice, BindingResult bindingResult){
+        ValidationKit.ignoreFields(bindingResult,"id");
+        imGroupNoticeService.create(imGroupNotice);
+        return succeed();
+    }
+
+    @ApiOperation("删除群公告")
+    @PostMapping(value = "/del/{noticeId}")
+    public HttpResponseResult del(@ApiParam(value = "群公告编号", required = true) @PathVariable("noticeId") Long noticeId){
+        imGroupNoticeService.del(noticeId);
+        return succeed();
+    }
+
+    @ApiOperation("修改群公告")
+    @PostMapping(value = "/update")
+    public HttpResponseResult modify(@Valid @RequestBody ImGroupNotice imGroupNotice){
+        imGroupNoticeService.modify(imGroupNotice);
+        return succeed();
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "groupId", dataType = "Long", value = "群编号",required = true)
+    })
+    @ApiOperation("分页查询")
+    @PostMapping(value = "/queryPage")
+    public HttpResponseResult<PageInfo<ImGroupNoticeDto>> queryPage(@RequestBody Map<String,Object> params) throws Exception {
+        return succeed(imGroupNoticeService.queryPage(params));
+    }
+}
+

+ 102 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/ImUserFriendController.java

@@ -0,0 +1,102 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.entity.ImUserFriend;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.vo.im.ImUserFriendVO;
+import com.yonge.cooleshow.biz.dal.wrapper.im.ImUserWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 用户通讯录表(ImUserFriend)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:59
+ */
+@Api(tags = "用户通讯录表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/imUserFriend")
+public class ImUserFriendController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private ImUserFriendService imUserFriendService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @SuppressWarnings("unchecked")//因为返回是集合,这里提示你集合内容较多排序可能回耗费性能
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "search", dataType = "String", value = "根据用户编号、昵称模糊查询")
+    })
+    @ApiOperation("获取通讯录成员列表")
+    @PostMapping(value = "/queryAll")
+    public HttpResponseResult<List<ImUserWrapper.ImUserFriend>> queryAll(@RequestBody Map<String, Object> params) {
+
+        // 用户ID
+        Long userId = sysUserService.getUserId();
+
+        // 学生好友列表
+        List<ImUserWrapper.ImUserFriend> userFriends = imUserFriendService.findUserAllImFriendInfo(ClientEnum.TEACHER, userId, params);
+
+        /*Object search = params.get("search");
+        List<ImUserFriend> record = imUserFriendService.list(Wrappers.<ImUserFriend>query().lambda()
+                .eq(ImUserFriend::getUserId, sysUserService.getUserId())
+                .and(Objects.nonNull(search) && StringUtils.isNotEmpty(search.toString()),
+                        e -> e.eq(ImUserFriend::getFriendId, search)
+                                .or().like(ImUserFriend::getFriendNickname, search))
+                .orderByDesc(ImUserFriend::getId));
+
+        for (ImUserFriend item : record) {
+
+            // 老师端添加好友,可能为老师客服或者学生
+            item.clientType(ClientEnum.STUDENT)
+                    .setImFriendId(MessageFormat.format("{0}:{1}", String.valueOf(item.getFriendId()), ClientEnum.STUDENT.name()));
+        }*/
+
+        return succeed(userFriends);
+    }
+
+    @ApiOperation("获取好友详情")
+    @PostMapping(value = "/getDetail/{userId}")
+    public HttpResponseResult<ImUserFriendVO.ImUserFriend> getDetail(@ApiParam(value = "用户编号", required = true) @PathVariable("userId") String userId) {
+
+        String ret = userId.split(":")[0];
+        if (!ret.matches(MK.EXP_INT)) {
+            return failed("无效的用户ID");
+        }
+
+        ImUserFriend userFriend = imUserFriendService.getDetail(userId, ClientEnum.TEACHER);
+        if (Objects.isNull(userFriend)) {
+            return failed("当前好友不存在");
+        }
+
+        if (Objects.isNull(userFriend.getFriendType())) {
+            userFriend.setFriendType(ClientEnum.STUDENT);
+        }
+
+        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+    }
+
+}
+

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

@@ -0,0 +1,60 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.search.MemberPriceSettingsSearch;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.vo.MemberPriceSettingsVo;
+import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RequestMapping("${app-config.url.teacher:}/memberPriceSettings")
+@Api(tags = "会员价格设置")
+@RestController
+public class MemberPriceSettingsController extends BaseController {
+	@Autowired
+	private MemberPriceSettingsService memberPriceSettingsService;
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	/**
+	 * 查询单条
+	 */
+	@GetMapping("/detail/{id}")
+	@ApiOperation(value = "详情", notes = "传入id")
+	public HttpResponseResult<MemberPriceSettingsVo> detail(@PathVariable("id") Long id) {
+		return succeed(memberPriceSettingsService.detail(id)); 
+	}
+
+	@PostMapping("/list")
+	@ApiOperation(value = "查询列表")
+	public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
+		MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
+		return succeed(memberPriceVo);
+	}
+
+	@PostMapping("/vipPermissions")
+	@ApiOperation(value = "查询vip权限")
+	public HttpResponseResult<List<SysConfig>> vipPermissions() {
+		Map<String,Object> params = new HashMap<>();
+		params.put("group", "VIP_PERMISSION");
+		List<SysConfig> configs = sysConfigService.findAll(params);
+		return succeed(configs);
+	}
+
+
+}

+ 207 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicAlbumController.java

@@ -0,0 +1,207 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicAlbumDetailSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicAlbumSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicAlbumSearch;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.vo.AlbumDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 专辑表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/music/album")
+@Api(tags = "专辑表 API接口")
+public class MusicAlbumController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicAlbumService musicAlbumService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    @ApiOperation(value = "分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> list(@RequestBody MusicAlbumSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        Teacher teacher = teacherService.getById(sysUser.getId());
+        if (teacher == null) {
+            return failed("用户信息获取失败");
+        }
+        
+        if(query.getSubjectIdList() == null || query.getSubjectIdList().size() == 0){
+        	List<Long> subjectIdList = new ArrayList<Long>();
+        	if(StringUtils.isNotBlank(teacher.getSubjectId())){
+        		String[] subjectIds = teacher.getSubjectId().split(",");
+        		for(String s : subjectIds){
+                	subjectIdList.add(Long.parseLong(s));
+        		}
+        		query.setSubjectIdList(subjectIdList);
+        	}
+        }
+
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+        query.setAlbumStatus(YesOrNoEnum.YES);
+        query.setSortBy(1);
+        query.setUserId(sysUser.getId());
+        IPage<MusicAlbumVo> iPage = musicAlbumService.selectStudentPage(PageUtil.getPage(query),query, ClientEnum.TEACHER);
+        return succeed(PageUtil.pageInfo(iPage));
+    }
+
+
+    /**
+     * 专辑详情
+     */
+    @PostMapping(value = "/detail",  consumes="application/json", produces="application/json")
+    @ApiOperation(value = "专辑详情",httpMethod="POST", consumes="application/json", produces="application/json")
+    public HttpResponseResult<AlbumDetailVo> detail(@Valid @RequestBody MusicAlbumDetailSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        query.setType(2);
+        query.setState(YesOrNoEnum.YES);
+        YesOrNoEnum yesOrNoEnum = musicAlbumService.checkFavorite(sysUser.getId(),query.getId(), ClientEnum.TEACHER);
+        AlbumDetailVo albumDetailVo = musicAlbumService.detail(PageUtil.getPage(query), query, sysUser,  ClientEnum.TEACHER);
+        albumDetailVo.setFavorite(yesOrNoEnum);
+
+        // 相关专辑
+        MusicAlbumSearch musicAlbumSearch = new MusicAlbumSearch();
+        musicAlbumSearch.setAuditVersion(YesOrNoEnum.NO);
+        musicAlbumSearch.setAlbumStatus(YesOrNoEnum.YES);
+        musicAlbumSearch.setAuditVersion(albumDetailVo.getAuditVersion());
+        musicAlbumSearch.setSortBy(1);
+        musicAlbumSearch.setPage(1);
+        musicAlbumSearch.setRows(query.getRelatedNum() +1);
+        musicAlbumSearch.setAlbumTagIds(albumDetailVo.getAlbumTag());
+        IPage<MusicAlbumVo> relatedMusicAlbum = musicAlbumService.selectStudentPage(PageUtil.getPage(musicAlbumSearch),musicAlbumSearch, ClientEnum.TEACHER);
+        List<MusicAlbumVo> musicAlbumVos1 = relatedMusicAlbum.getRecords()
+                                                      .stream()
+                                                      .filter(musicAlbumVo -> !musicAlbumVo.getId()
+                                                                                           .equals(albumDetailVo.getId()))
+                                                      .collect(Collectors.toList());
+        if (musicAlbumVos1.size() > query.getRelatedNum()) {
+            musicAlbumVos1 = musicAlbumVos1.subList(0,query.getRelatedNum());
+        }
+        albumDetailVo.setRelatedMusicAlbum(musicAlbumVos1);
+        return succeed(albumDetailVo);
+    }
+
+    /**
+     * 专辑收藏
+     */
+     @PostMapping("/favorite/{id}")
+    @ApiOperation(value = "专辑收藏/取消收藏")
+    public HttpResponseResult<Boolean> favorite(@ApiParam(value = "专辑编号", required = true) @PathVariable("id") Long id,
+                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "TEACHER") String clientType) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+         if (ClientEnum.invalid(clientType)) {
+             return failed("无效的客户端类型");
+         }
+
+        return succeed(musicAlbumService.setFavorite(sysUser.getId(), id, ClientEnum.valueOf(clientType)));
+    }
+
+
+    /**
+     * 专辑收藏
+     */
+    @GetMapping("/favorite")
+    @ApiOperation(value = "收藏专辑列表")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> favoriteAlbum(QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        StudentMusicAlbumSearch search = new StudentMusicAlbumSearch();
+        search.studentId(sysUser.getId())
+                .albumFavorite(true)
+                 .setAlbumStatus(YesOrNoEnum.YES);
+
+        IPage<MusicAlbumVo> albumVoIPage = musicAlbumService.favoriteAlbum(PageUtil.getPage(query), search, ClientEnum.TEACHER);
+        return succeed(PageUtil.pageInfo(albumVoIPage));
+    }
+
+    /**
+     * 已购买专辑信息
+     * @return HttpResponseResult<PageInfo<MusicAlbumVo>>
+     */
+    @ApiOperation(value = "已购买专辑信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "gift", value = "课程赠品 0:购买 1:赠品, 默认值: 0"),
+            @ApiImplicitParam(name = "page", value = "分页查询, 默认值: 1"),
+            @ApiImplicitParam(name = "row", value = "当前页行数, 默认值: 10"),
+    })
+    @GetMapping("/purchased")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> purchasedAlbumInfo(@RequestParam(value = "gift", required = false, defaultValue = "0") Integer gift,
+                                                                         QueryInfo query) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        StudentMusicAlbumSearch search = new StudentMusicAlbumSearch();
+        search.studentId(sysUser.getId())
+                .albumPurchased(true)
+                .purchaseType(PurchaseRecordTypeEnum.ALBUM)
+                .courseGift(gift)
+                .orderStatus(OrderStatusEnum.PAID)
+                .clientType(ClientEnum.TEACHER);
+
+        IPage<MusicAlbumVo> albumVoIPage = musicAlbumService.favoriteAlbum(PageUtil.getPage(query), search, ClientEnum.TEACHER);
+        return succeed(PageUtil.pageInfo(albumVoIPage));
+    }
+}

+ 401 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java

@@ -0,0 +1,401 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.AppMusicSheetVo;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetDto;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetRenderDto;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicSheetRelatedQueryInfo;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ChargeTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MusicSortType;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetShareVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/music/sheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetService musicSheetService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入musicTag")
+    public HttpResponseResult<MusicSheetDetailVo> detail(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") Long id) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        MusicSheetDetailVo detail = musicSheetService.detail(id, sysUser, ClientEnum.TEACHER);
+
+        // 设置返回默认值
+        if (StringUtil.isEmpty(detail.getAudioFileUrl())) {
+            detail.setAudioFileUrl("");
+        }
+        if (StringUtils.isEmpty(detail.getMusicImg())) {
+            detail.setMusicImg("");
+        }
+        return succeed(detail);
+    }
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/updateRenderFile", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> updateRenderFile(@Valid @RequestBody MusicSheetRenderDto musicSheetRenderDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheetRenderDto.getMusicSheetId()==null){
+            return failed("缺少ID");
+        }
+        MusicSheet musicSheet = musicSheetService.getById(musicSheetRenderDto.getMusicSheetId());
+        
+        if(musicSheet == null){
+        	return failed("参数异常");
+        }
+        musicSheet.setMusicFirstSvg(musicSheetRenderDto.getMusicFirstSvg());
+        musicSheet.setMusicJianSvg(musicSheetRenderDto.getMusicJianSvg());
+        musicSheet.setMusicJSON(musicSheetRenderDto.getMusicJSON());
+        musicSheet.setMusicSvg(musicSheetRenderDto.getMusicSvg());
+
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateTime(new Date());
+        if ( musicSheetService.updateById(musicSheet)){
+            return succeed("修改成功");
+        } else {
+            return failed("修改失败");
+        }
+    }
+
+	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicSheetDto musicSheetDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ChargeTypeEnum.CHARGE.getCode().equals(musicSheetDto.getChargeType().getCode())
+                && musicSheetDto.getMusicPrice()==null){
+            return failed("此曲谱为收费曲谱,需要提供价格");
+        }
+        if (musicSheetDto.getNotation() == null) {
+            musicSheetDto.setNotation(YesOrNoEnum.NO);
+        }
+
+        musicSheetDto.setUserId(sysUser.getId());
+        musicSheetDto.setAuditStatus(AuthStatusEnum.DOING);
+        musicSheetDto.setSubmitAuditTime(new Date());
+        musicSheetDto.setSourceType(SourceTypeEnum.TEACHER);
+
+        musicSheetDto.setFavoriteCount(0);
+        musicSheetDto.setCreateBy(sysUser.getId());
+        musicSheetDto.setCreateTime(new Date());
+        musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
+        return succeed("新增曲谱成功");
+    }
+
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetDto musicSheet) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheet.getId()==null){
+            return failed("缺少ID");
+        }
+        if (musicSheet.getNotation() == null) {
+            musicSheet.setNotation(YesOrNoEnum.NO);
+        }
+        musicSheet.setUserId(sysUser.getId());
+        musicSheet.setSubmitAuditTime(new Date());
+        musicSheet.setCreateTime(new Date());
+        musicSheet.setCreateBy(sysUser.getId());
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateTime(new Date());
+        musicSheet.setSubmitAuditTime(new Date());
+        musicSheet.setAuditStatus(AuthStatusEnum.DOING);
+        if ( musicSheetService.saveMusicSheet(musicSheet,sysUser.getId())){
+            return succeed("修改成功");
+        } else {
+            return failed("修改失败");
+        }
+    }
+
+    @ApiOperation(value = "曲目分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> list(@RequestBody StudentMusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 老师课查看所有曲目
+        if (query.getMyself() == null || query.getMyself()) {
+            // 设置只查老师用户 状态为启用
+            query.setCreateBy(sysUser.getId());
+            if (query.getAuditStatus() != null && AuthStatusEnum.PASS.getCode().equals(query.getAuditStatus().getCode())) {
+                query.setState(YesOrNoEnum.YES);
+            } else if (query.getAuditStatus() != null && AuthStatusEnum.OUT_SALE.getCode().equals(query.getAuditStatus().getCode())) {
+                query.setState(YesOrNoEnum.NO);
+                query.setAuditStatus(AuthStatusEnum.PASS);
+            }
+            query.setSourceType(SourceTypeEnum.TEACHER);
+            query.setMyself(true);
+        } else {
+            Teacher teacher = teacherService.getById(sysUser.getId());
+            if (teacher == null) {
+                return failed("用户信息获取失败");
+            }
+            if(StringUtils.isBlank(query.getSubjectIds())){
+            	query.setSubjectIds(teacher.getSubjectId());
+            }
+
+            // 检查app版本
+            query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+            //  只能看通过审核 并且 启用的 曲目
+            query.setState(YesOrNoEnum.YES);
+            query.setAuditStatus(AuthStatusEnum.PASS);
+            query.setStudentId(sysUser.getId());
+            query.setMyself(false);
+        }
+
+        IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.TEACHER);
+        return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+    }
+
+    /**
+     * 启用/停用
+     */
+    @PostMapping("/state/{id}")
+    @ApiOperation(value = "启用/停用", notes = "传入id")
+    public HttpResponseResult<Boolean> state(@ApiParam(value = "曲目编号", required = true)  @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        MusicSheet musicSheet = musicSheetService.getById(id);
+        if (musicSheet == null) {
+            return failed("未找到曲目");
+        }
+
+        if (musicSheet.getState().equals(YesOrNoEnum.NO)) {
+            return failed("曲目已被下架");
+        }
+        return status(musicSheetService.state(id, "", ClientEnum.TEACHER));
+    }
+
+    /**
+     * 曲目收藏
+     */
+    @PostMapping("/favorite/{id}")
+    @ApiOperation(value = "曲目收藏/取消收藏")
+    public HttpResponseResult<Boolean> favorite(@ApiParam(value = "曲目编号", required = true) @PathVariable("id") Long id,
+                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "TEACHER") String clientType) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        return succeed(musicSheetService.setFavorite(sysUser.getId(),id, ClientEnum.valueOf(clientType)));
+    }
+
+    /**
+     * 我的单曲
+     */
+    @PostMapping("/my")
+    @ApiOperation(value = "我的单曲")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> myMusic(@RequestBody  StudentMusicSheetSearch search) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        search.setStudentId(sysUser.getId());
+        // search.setState(YesOrNoEnum.YES);
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        search.setUserType(ClientEnum.TEACHER);
+        search.setPurchaseType(PurchaseRecordTypeEnum.MUSIC);
+        search.setCourseGift(Optional.ofNullable(search.getCourseGift()).orElse(EStatus.DISABLE.getValue()));
+
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.myMusic(PageUtil.getPage(search),search);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+    /**
+     * 收藏单曲
+     */
+    @GetMapping("/favorite")
+    @ApiOperation(value = "收藏单曲")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> favoriteMusic(QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setStudentId(sysUser.getId());
+        search.setState(YesOrNoEnum.YES);
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.favoriteMusic(PageUtil.getPage(query),search, ClientEnum.TEACHER);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+    @ApiOperation(value = "乐谱分享")
+    @GetMapping(value="/share")
+    public HttpResponseResult<MusicSheetShareVo> shareMusicSheet() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(musicSheetService.shareMusicSheet(sysUser));
+    }
+
+
+    @ApiOperation(value = "我的乐谱数量")
+    @GetMapping(value="/count")
+    public HttpResponseResult<Integer> countTeacherMusicSheet() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(musicSheetService.countTeacherMusicSheet(sysUser));
+    }
+
+    @ApiOperation(value = "关联的曲目列表")
+    @GetMapping(value="/queryRelatedList")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
+    	
+    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo.getAlbumId(), queryInfo.getMusicSheetId());
+        return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+    }
+
+
+    @ApiOperation(value = "app首页曲目数据", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/appMusicSheet", consumes="application/json", produces="application/json")
+    public HttpResponseResult<AppMusicSheetVo> appMusicSheet(@RequestBody StudentMusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        Teacher teacher = teacherService.getById(sysUser.getId());
+        if (teacher == null) {
+            return failed("用户信息获取失败");
+        }
+        if(StringUtils.isBlank(query.getSubjectIds())){
+            query.setSubjectIds(teacher.getSubjectId());
+        }
+
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+        //  只能看通过审核 并且 启用的 曲目
+        query.setState(YesOrNoEnum.YES);
+        query.setAuditStatus(AuthStatusEnum.PASS);
+        query.setStudentId(sysUser.getId());
+        query.setMyself(false);
+        query.setRows(20);
+
+        AppMusicSheetVo appMusicSheetVo = new AppMusicSheetVo();
+        // 推荐曲目
+        query.setMusicSortType(MusicSortType.TOP);
+        appMusicSheetVo.setTopMusicSheet(musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.TEACHER).getRecords());
+
+        // 审核版本只返回一列
+        if (query.getAuditVersion().equals(YesOrNoEnum.YES)) {
+            appMusicSheetVo.setHotMusicSheet(new ArrayList<>());
+            appMusicSheetVo.setNewMusicSheet(new ArrayList<>());
+        } else {
+            // 最热曲目
+            query.setMusicSortType(MusicSortType.HOT);
+            appMusicSheetVo.setHotMusicSheet(
+                    musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.STUDENT).getRecords());
+
+            // 最新曲目
+            query.setMusicSortType(MusicSortType.NEW);
+            appMusicSheetVo.setNewMusicSheet(
+                    musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.STUDENT).getRecords());
+        }
+        return succeed(appMusicSheetVo);
+    }
+
+
+    /**
+     * 最近练习
+     */
+    @GetMapping("/user/practice")
+    @ApiOperation(value = "老师查看学生最近练习")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> practiceMusic(@RequestParam Long userId) {
+
+        if (userId == null) {
+            return failed("用户信息不存在");
+        }
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setStudentId(userId);
+        search.setState(YesOrNoEnum.YES);
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        search.setRows(3);
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.practiceMusic(PageUtil.getPage(search),search);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+}

+ 34 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/MusicTagController.java

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.service.MusicTagService;
+import com.yonge.cooleshow.biz.dal.vo.MusicTagVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/MusicTag")
+@Api(value = "音乐标签表", tags = "音乐标签表")
+public class MusicTagController extends BaseController {
+
+    @Autowired
+    private MusicTagService musicTagService;
+
+	/**
+	 * 查询分页tree
+	 */
+	@GetMapping("/tree")
+	@ApiOperation(value = "查询标签树列表")
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
+		return succeed(treeList);
+	}
+
+}

+ 48 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/PianoRoomBuyRecordController.java

@@ -0,0 +1,48 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomBuyRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.PianoRoomBuyRecordService;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomBuyRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/pianoRoomBuyRecord")
+@Api(value = "购买琴房记录表", tags = "购买琴房记录表")
+public class PianoRoomBuyRecordController extends BaseController {
+
+    @Autowired
+    private PianoRoomBuyRecordService pianoRoomBuyRecordService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<PianoRoomBuyRecordVo> detail(@PathVariable("id") Long id) {
+    	return succeed(pianoRoomBuyRecordService.detail(id));
+	}
+    
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入pianoRoomBuyRecordSearch")
+    public HttpResponseResult<PageInfo<PianoRoomBuyRecordVo>> page(@RequestBody PianoRoomBuyRecordSearch query) {
+		IPage<PianoRoomBuyRecordVo> pages = pianoRoomBuyRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+	}
+
+}

+ 45 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/PianoRoomSettingsController.java

@@ -0,0 +1,45 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.search.PianoRoomSettingsSearch;
+import com.yonge.cooleshow.biz.dal.service.PianoRoomSettingsService;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomSettingsVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/pianoRoomSettings")
+@Api(value = "琴房时长价格配置", tags = "琴房时长价格配置")
+public class PianoRoomSettingsController extends BaseController {
+
+    @Autowired
+    private PianoRoomSettingsService pianoRoomSettingsService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<PianoRoomSettingsVo> detail(@PathVariable("id") Long id) {
+        return succeed(pianoRoomSettingsService.detail(id));
+    }
+
+    @PostMapping("/list")
+    @ApiOperation(value = "查询列表")
+    public HttpResponseResult<List<PianoRoomSettingsVo>> list(@RequestBody PianoRoomSettingsSearch query) {
+        query.setStatus(YesOrNoEnum.YES.getCode());
+        List<PianoRoomSettingsVo> list = pianoRoomSettingsService.selectList(query);
+        return succeed(list);
+    }
+}

+ 88 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String,String> redisTemplate;
+
+    @ApiOperation(value = "发送短信验证码")
+    @ApiImplicitParams({  @ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
+                          @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号,LOGOFF:用户注销)", required = true, dataType = "String") })
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile,String type) throws Exception {
+        smsCodeService.sendValidCode(mobile, type, ClientEnum.TEACHER);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+                         @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
+                         @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String") })
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone,String code,String type) {
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if(smsCodeService.verifyValidCode(phone, code, type)){
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({ @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String") })
+    public Object verifyImageCode(String phone,String code){
+        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if(redisTemplate.hasKey(redisKey)){
+            if(StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey),code)){
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response,String phone) throws Exception {
+        if(StringUtils.isEmpty(phone)){
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone,specCaptcha.text(),3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

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

@@ -0,0 +1,44 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.util.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/student")
+@Api(value = "学生表", tags = "学生表")
+public class StudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+
+
+    @ApiOperation(value = "查询指定学员信息-融云token")
+    @GetMapping("/queryUserById")
+    public HttpResponseResult<StudentVo> queryUserById(String rongCloudUserId) {
+
+        if (StringUtil.isEmpty(rongCloudUserId)) {
+            return failed("用户信息获取失败");
+        }
+
+        Long userId = null;
+        String[] split = rongCloudUserId.split(":");
+        if (split.length == 2 && !StringUtil.isEmpty(split[0])) {
+            try {
+                userId = Long.parseLong(split[0]);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return failed("用户信息获取失败");
+            }
+        }
+        return succeed(studentService.detail(userId));
+    }
+
+}

+ 60 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SubjectController.java

@@ -0,0 +1,60 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RequestMapping("${app-config.url.teacher:}/subject")
+@Api(tags = "声部服务")
+@RestController
+public class SubjectController extends BaseController {
+
+	@Autowired
+	private SubjectService subjectService;
+	
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    
+    @Autowired
+    private TeacherService teacherService;
+
+	@ApiOperation(value = "根据声部编号查询声部")
+	@GetMapping("/get/{id}")
+	public Object get(@ApiParam(value = "声部编号", required = true) @PathVariable("id") Long id) {
+		return succeed(subjectService.get(id));
+	}
+
+	@ApiOperation(value = "获取声部")
+	@GetMapping("/subjectSelect")
+    public HttpResponseResult<List<Subject>> subjectSelect(
+			@ApiParam(value = "类型 PRACTICE 陪练课 LIVE 直播课 VIDEO 视频课 PIANO_ROOM 琴房 MUSIC 曲目 ") String type){
+		
+		String userExtSubjectIds = null;
+        
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser != null && sysUser.getId() != null) {
+        	Teacher teacher = teacherService.getById(sysUser.getId());
+        	if(teacher != null && teacher.getDefaultSubject() != null){
+        		userExtSubjectIds = teacher.getDefaultSubject().toString();
+        	}
+        }
+        
+        List<Subject> subjectSelect = subjectService.subjectSelect(type, userExtSubjectIds);
+        return succeed(subjectSelect);
+    }
+}

+ 82 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysConfigController.java

@@ -0,0 +1,82 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.utils.http.HttpUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** 
+ * 系统配置控制层
+ */
+@RestController
+@Api(tags = "系统参数设置")
+@RequestMapping(value = "${app-config.url.teacher:}/sysConfig")
+public class SysConfigController extends BaseController {
+
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	@ApiOperation(value = "参数列表")
+	@GetMapping(value = "list")
+	public Object configList(String group) {
+		Map<String,Object> params = new HashMap<String, Object>();
+		params.put("group", group);
+		List<SysConfig> configs = sysConfigService.findAll(params);
+		return succeed(configs);
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "get")
+	public Object getConfig(Long id) {
+		if (id == null || id <= 0)
+			return failed("请检查输入的ID");
+		return succeed(sysConfigService.get(id));
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "queryByParamName")
+	public Object queryByParamName(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findByParamName(paramName));
+	}
+
+	@GetMapping(value = "findConfigValue")
+	public HttpResponseResult<String> findConfigValue(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findConfigValue(paramName));
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "queryByParamNameList")
+	public Object queryByParamNameList(String paramNames) {
+		if(StringUtils.isBlank(paramNames)){
+			return failed("参数不能为空");
+		}
+		List<String> paramNameList = Arrays.asList(paramNames.split(","));
+		return succeed(sysConfigService.findByParamName(paramNameList));
+	}
+
+	@ApiOperation(value = "url短链接")
+	@PostMapping("shortURL")
+	public HttpResponseResult<String> shortURL(String orginURL) {
+		return succeed(HttpUtil.getSortUrl(orginURL));
+	}
+}

+ 47 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysImComplaintController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.SysImComplaint;
+import com.yonge.cooleshow.biz.dal.service.SysImComplaintService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+
+/**
+ * (SysImComplaint)表控制层
+ *
+ * @author zx
+ * @since 2022-06-13 16:37:00
+ */
+@RestController
+@Api(tags = "消息(群组)投诉")
+@RequestMapping("${app-config.url.teacher:}/sysImComplaint")
+public class SysImComplaintController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private SysImComplaintService sysImComplaintService;
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "新增")
+    @PostMapping("/add")
+    public HttpResponseResult<Boolean> add(@RequestBody SysImComplaint sysImComplaint) {
+        sysImComplaint.setUserId(sysUserService.getUserId());
+        Date now = new Date();
+        sysImComplaint.setUpdateTime(now);
+        sysImComplaint.setCreateTime(now);
+        return succeed(sysImComplaintService.save(sysImComplaint));
+    }
+
+}
+

+ 131 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMessageController.java

@@ -0,0 +1,131 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dao.AppVersionInfoDao;
+import com.yonge.cooleshow.biz.dal.dto.search.SysMessageQueryInfo;
+import com.yonge.cooleshow.biz.dal.entity.SysMessage;
+import com.yonge.cooleshow.biz.dal.enums.MessageSendMode;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.entity.Mapper;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
+import com.yonge.toolset.utils.validator.CommonValidator;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@Api(tags = "消息服务")
+@RequestMapping("${app-config.url.teacher:}/sysMessage")
+public class SysMessageController extends BaseController {
+
+	@Autowired
+	private SysMessageService sysMessageService;
+
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private AppVersionInfoDao appVersionInfoDao;
+
+	@ApiOperation("获取所有消息列表")
+	@PostMapping(value = "list")
+	public HttpResponseResult<PageInfo<SysMessage>> list(@RequestBody SysMessageQueryInfo queryInfo){
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		queryInfo.setUserId(sysUser.getId());
+		queryInfo.setType(MessageSendMode.PUSH.getCode());
+		queryInfo.setClientId("TEACHER");
+		return succeed(sysMessageService.queryPage(queryInfo));
+	}
+
+	// @ApiOperation("获取消息分类类型")
+	// @GetMapping(value = "typeList")
+	// public Object typeList(String memo){
+	// 	//如果用户使用的版本比当前版本号大,那么屏蔽缴费信息
+	// 	if(StringUtils.isNotEmpty(memo)){
+	// 		//获取当前使用的版本
+	// 		AppVersionInfo appVersionInfo = appVersionInfoDao.queryNewestByPlatform("ios-student").get(0);
+	// 		int defaultVersion = Integer.parseInt(appVersionInfo.getVersion().replaceAll("\\.",""));
+	// 		int currentVersion = Integer.parseInt(memo.replaceAll("\\.",""));
+	// 		if(currentVersion > defaultVersion){
+	// 			return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
+	// 					"{\"value\":\"课程信息\",\"key\":\"COURSE\"}," +
+	// 					"{\"value\":\"训练信息\",\"key\":\"WORK\"}," +
+	// 					"{\"value\":\"其他\",\"key\":\"DEFAULT\"}]"));
+	// 		}
+	// 	}
+	// 	return succeed(JSON.parseArray("[{\"value\":\"全部\",\"key\":\"ALL\"}," +
+	// 			"{\"value\":\"缴费信息\",\"key\":\"PAY\"}," +
+	// 			"{\"value\":\"课程信息\",\"key\":\"COURSE\"}," +
+	// 			"{\"value\":\"训练信息\",\"key\":\"WORK\"}," +
+	// 			"{\"value\":\"其他\",\"key\":\"DEFAULT\"}]"));
+	// }
+
+	@ApiOperation("一键已读")
+	@PostMapping("batchSetRead")
+	public Object batchSetRead() {
+		int status = 1;
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		return succeed(sysMessageService.updateStatus(sysUser.getId(), status,"TEACHER") > 0 );
+	}
+
+	@ApiOperation("设置已读")
+	@PostMapping("setRead/{id}")
+	public Object setRead(@PathVariable Long id) {
+		int status = 1;
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		return succeed(sysMessageService.updateOneStatus(id, status) >0) ;
+	}
+
+	@ApiOperation(value = "查询用户未读消息条数")
+	@GetMapping("/queryCountOfUnread")
+	public HttpResponseResult<List<Mapper>> queryCountOfUnread() {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		List<Mapper>  map = sysMessageService.queryCountOfUnread(MessageSendMode.PUSH, sysUser.getId(), "TEACHER");
+
+		return succeed(map);
+	}
+
+	@ApiOperation(value = "发送消息")
+	@PostMapping("/sendMessage")
+	public Object sendMessage(MessageSenderPluginContext.MessageSender messageSender, String content, String receiver, int readStatus, String url, String group) {
+		SysUser sysUser = sysUserFeignService.queryUserInfo();
+		if (sysUser == null) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		Long userId = sysUser.getId();
+
+		String mobileNo = sysUser.getPhone();
+		if (StringUtils.isBlank(mobileNo) || !CommonValidator.isMobileNo(mobileNo)) {
+			throw new BizException("请输入正确的手机号");
+		}
+		sysMessageService.sendMessage(messageSender, userId, "", content, receiver, null, readStatus, url, group, "TEACHER");
+		return succeed(true);
+	}
+}

+ 84 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysMusicCompareRecordController.java

@@ -0,0 +1,84 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.Objects;
+
+/**
+ * @Author Joburgess
+ * @Date 2021/8/13 0013
+ */
+@Api(tags = "小酷Ai记录")
+@RequestMapping("${app-config.url.teacher:}/sysMusicRecord")
+@RestController
+public class SysMusicCompareRecordController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+    @ApiOperation(value = "添加记录")
+    @PostMapping("add")
+    public HttpResponseResult add(SysMusicCompareRecord record){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        if(Objects.isNull(record.getFeature())){
+            return failed("请设置功能点");
+        }
+        record.setUserId(sysUser.getId());
+        record.setClientId(ClientEnum.TEACHER.name().toLowerCase());
+        return succeed(sysMusicCompareRecordService.insert(record));
+    }
+
+    @ApiOperation(value = "用户最后一次评测数据")
+    @GetMapping("getLastEvaluationMusicalNotesPlayStats")
+    public HttpResponseResult getLastEvaluationMusicalNotesPlayStats(Long recordId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
+    }
+
+    @ApiOperation("老师训练数据统计")
+    @GetMapping("studentTrainData")
+    public HttpResponseResult studentTrainData(SysMusicCompareRecordQueryInfo.TeacherCompareRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        queryInfo.setUserId(sysUser.getId());
+        queryInfo.setClientId("teacher");
+        if (StringUtils.isEmpty(queryInfo.getStartTime())) {
+            return failed("时间不能为空");
+        }
+        LocalDate localDate = LocalDate.parse(queryInfo.getStartTime() + "-01",
+                                              DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+        queryInfo.setStartTime(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        LocalDate endDate = localDate.plusDays(localDate.getMonth().length(localDate.isLeapYear()) -1);
+        queryInfo.setEndTime(endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+        return succeed(sysMusicCompareRecordService.studentTrainData(queryInfo));
+    }
+
+}

+ 41 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysSuggestionController.java

@@ -0,0 +1,41 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.service.SysSuggestionService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "意见反馈")
+@RestController
+@RequestMapping("${app-config.url.teacher:}")
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId().longValue());
+        sysSuggestion.setClientType("TEACHER");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+}

+ 85 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/SysUserContractRecordController.java

@@ -0,0 +1,85 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.ContractTemplate;
+import com.yonge.cooleshow.biz.dal.service.ContractService;
+import com.yonge.cooleshow.biz.dal.service.ContractTemplateService;
+import com.yonge.cooleshow.biz.dal.service.SysUserContractRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.ContractTemplateTypeEnum;
+import com.yonge.cooleshow.common.enums.SysUserType;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 用户协议记录表-一个用户一种协议一个版本一条记录(SysUserContractRecord)表控制层
+ *
+ * @author hgw
+ * @since 2022-05-07 15:04:05
+ */
+@Api(tags = "用户协议记录表-一个用户一种协议一个版本一条记录")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/sysUserContractRecord")
+public class SysUserContractRecordController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private ContractTemplateService contractTemplateService;
+    @Autowired
+    private SysUserContractRecordService sysUserContractRecordService;
+    @Autowired
+    private ContractService contractService;
+
+    @ApiOperation("判断用户是否签署协议")
+    @GetMapping(value = "/checkContractSign", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public HttpResponseResult<Boolean> checkContractSign(@ApiParam(value = "业务类型 REGISTER 注册 COURSES 课程购买 PRODUCT 产品 WITHDRAW 结算", required = true) @RequestParam("contractType") ContractTemplateTypeEnum contractType) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return HttpResponseResult.succeed(sysUserContractRecordService.checkContractSign(user.getId(), SysUserType.TEACHER, contractType));
+    }
+
+    @ApiOperation("查看协议-获取协议模板")
+    @GetMapping(value = "/queryLatestContractTemplate")
+    public HttpResponseResult<ContractTemplate> queryLatestContractTemplate(@ApiParam(value = "业务类型 REGISTER 注册 COURSES 课程购买 PRODUCT 产品 WITHDRAW 结算", required = true) @RequestParam("contractType") ContractTemplateTypeEnum contractType) {
+        return succeed(contractTemplateService.queryLatestContractTemplate(contractType));
+    }
+
+    @ApiOperation("查看协议-获取协议内容")
+    @GetMapping(value = "/queryContract", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public HttpResponseResult<String> queryContract(
+            @ApiParam(value = "协议类型", required = true) @RequestParam("contractType") ContractTemplateTypeEnum contractType) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return contractService.queryProductContract(user.getId(),SysUserType.TEACHER,contractType);
+    }
+
+    @ApiOperation("签署协议")
+    @GetMapping(value = "/sign", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
+    public HttpResponseResult<Boolean> sign(
+            @ApiParam(value = "协议类型", required = true) @RequestParam("contractType") ContractTemplateTypeEnum contractType) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return sysUserContractRecordService.sign(contractType, SysUserType.TEACHER, user);
+    }
+
+
+
+}
+

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

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.biz.dal.service.TeacherAttendanceService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 老师考勤表(TeacherAttendance)表控制层
+ *
+ * @author hgw
+ * @since 2022-05-05 13:51:02
+ */
+@Api(tags = "老师考勤表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/teacherAttendance")
+public class TeacherAttendanceController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private TeacherAttendanceService teacherAttendanceService;
+
+}
+

+ 52 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherAuthEntryRecordController.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherApplyDetailReq;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthEntryRecordService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/teacherAuthEntryRecord")
+@Api(value = "老师入驻审核表", tags = "老师入驻审核表")
+public class TeacherAuthEntryRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthEntryRecordService teacherAuthEntryRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @GetMapping("/getLastRecordByUserId")
+    @ApiOperation(value = "获取最近一次提交的申请内容")
+    public HttpResponseResult<TeacherAuthEntryRecordVo> getLastRecordByUserId() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TeacherAuthEntryRecordVo detail = teacherAuthEntryRecordService.getLastRecordByUserId(user.getId());
+        return succeed(detail);
+    }
+
+    @PostMapping("/doApply")
+    @ApiOperation(value = "提交申请", notes = "传入teacherAuthEntryRecord")
+    public HttpResponseResult<Boolean> doApply(@Valid @RequestBody TeacherApplyDetailReq teacherApplyDetailDto) throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        //处理老师申请逻辑
+        return teacherAuthEntryRecordService.doApply(teacherApplyDetailDto, user);
+    }
+}

+ 49 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherAuthMusicianRecordController.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthMusicianRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/teacherAuthMusicianRecord")
+@Api(value = "老师音乐人审核表", tags = "老师音乐人审核表")
+public class TeacherAuthMusicianRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthMusicianRecordService teacherAuthMusicianRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 获取音乐人审核状态
+     */
+    @GetMapping("/getMusicianAuthStatus")
+    @ApiOperation(value = "获取音乐人审核状态")
+    public HttpResponseResult<AuthStatusEnum> getMusicianAuthStatus() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        AuthStatusEnum musicianAuthStatus = teacherAuthMusicianRecordService.getMusicianAuthStatus(user.getId());
+        return succeed(musicianAuthStatus);
+    }
+
+    @PostMapping("/doApply")
+    @ApiOperation(value = "提交申请", notes = "传入teacherAuthEntryRecord")
+    public HttpResponseResult<Boolean> doApply() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        //处理老师申请逻辑
+        return teacherAuthMusicianRecordService.doApply(sysUser.getId());
+    }
+
+}

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

@@ -0,0 +1,283 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.dto.RealnameAuthReq;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantUnbindRecord;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
+import com.yonge.cooleshow.biz.dal.vo.MyFens;
+import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.ETenantUnBindAuditStatus;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/${app-config.url.teacher:}teacher")
+@Api(value = "教师表", tags = "教师表")
+public class TeacherController extends BaseController {
+    @Autowired
+    private TeacherService teacherService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @ApiOperation(value = "我的-查询教师基本信息")
+    @GetMapping("/queryUserInfo")
+    public HttpResponseResult<TeacherHomeVo> queryUserInfo() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return teacherService.queryUserInfo(user.getId());
+    }
+
+    @ApiOperation(value = "开通直播")
+    @GetMapping("/openLive")
+    public HttpResponseResult<Boolean> openLive() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return teacherService.openLive(user.getId());
+    }
+
+    @ApiOperation(value = "获取老师可授课声部列表")
+    @PostMapping("/querySubject")
+    public HttpResponseResult<List<Subject>> querySubject() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(teacherService.querySubject(user.getId()));
+    }
+
+    @ApiOperation(value = "设置声部")
+    @GetMapping("/setSubject")
+    public HttpResponseResult setSubject(@ApiParam(value = "声部主键集合", required = true) @RequestParam("subjectIds") String subjectIds) {
+        if (StringUtil.isEmpty(subjectIds)) {
+            return failed("参数不能为空");
+        }
+
+        if (subjectIds.split(",").length > 5) {
+            return failed("最多选择5个乐器");
+        }
+
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(teacherService.setSubject(user.getId(), subjectIds) > 0);
+    }
+
+    @ApiOperation(value = "获取声部搜索下拉框")
+    @PostMapping("/querySubjectItem")
+    public HttpResponseResult<List<Subject>> querySubjectItem(
+            @ApiParam(value = "类型 PRACTICE 陪练课 LIVE 直播课 VIDEO 视频课 PIANO_ROOM 琴房 MUSIC 曲目 ") String type) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(teacherService.querySubjectItem(user.getId(), type));
+    }
+
+    @ApiOperation(value = "我的-个人风采")
+    @GetMapping("/queryTeacherStyle")
+    public HttpResponseResult<TeacherVo> queryTeacherStyle() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return HttpResponseResult.succeed(teacherService.detail(user.getId()));
+    }
+
+    @ApiOperation(value = "我的-个人风采保存")
+    @PostMapping("/saveTeacherStyle")
+    public HttpResponseResult<TeacherVo> saveTeacherStyle(@RequestBody TeacherDto teacherDto) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(teacherDto.getSubjectId())) {
+            return failed("请选择乐器");
+        }
+        teacherDto.setUserId(user.getId());
+        return teacherService.saveTeacherStyle(teacherDto);
+    }
+
+    @ApiOperation(value = "我的粉丝")
+    @PostMapping(value = "/queryMyFans")
+    public HttpResponseResult<PageInfo<MyFens>> queryMyFans(@RequestBody QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        IPage<MyFens> pages = teacherService.queryMyFans(PageUtil.getPage(query), sysUser.getId());
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+
+    /**
+     * 最近练习
+     */
+    @PostMapping("/defaultSubject")
+    @ApiOperation(value = "设置老师默认查询声部")
+    public HttpResponseResult defaultSubject(@RequestParam(required = false) Long subjectId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (subjectId == null) {
+            return succeed();
+        }
+        Teacher teacher = new Teacher();
+        teacher.setUserId(sysUser.getId());
+        teacher.setDefaultSubject(subjectId);
+        return succeed(teacherService.updateById(teacher));
+    }
+
+    @PostMapping("/realNameAuth")
+    @ApiOperation(value = "实名认证", notes = "传入realNameAuthDto")
+    @ResponseBody
+    public HttpResponseResult<IdcardInfoExtractor> realNameAuth(@Valid @RequestBody RealnameAuthReq realNameAuthDto) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        IdcardInfoExtractor idcardInfoExtractor = sysUserService.updateUserCard(realNameAuthDto, user,
+                ClientEnum.TEACHER);
+        return succeed(idcardInfoExtractor);
+    }
+
+    @PostMapping("/unbindTenant")
+    @ApiOperation(value = "解绑机构申请")
+    public HttpResponseResult<Boolean> unbindTenant(@Validated @RequestBody TeacherWrapper.UnbindTenant unbindTenant) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        boolean validCode = smsCodeService.verifyValidCode(user.getPhone(), unbindTenant.getCode(), "");
+        if (!validCode) {
+            return failed("验证码错误");
+        }
+        if (user.getTenantId() == null || user.getTenantId() == -1) {
+            return failed("非机构用户不需要解绑");
+        }
+
+        Teacher teacher = teacherService.getById(user.getId());
+        if (teacher == null) {
+            return failed("未查询到老师的信息");
+        }
+
+        TenantUnbindRecord one = tenantUnbindRecordService.lambdaQuery()
+                .eq(TenantUnbindRecord::getUserType, "TEACHER")
+                .eq(TenantUnbindRecord::getUserId, user.getId())
+                .last("limit 1").one();
+        if (one != null && ETenantUnBindAuditStatus.DOING.equals(one.getStatus())) {
+            return failed("请勿重复提交申请");
+        }
+        TenantInfo tenantInfo = tenantInfoService.getById(user.getTenantId());
+        TenantUnbindRecord tenantUnbindRecord = new TenantUnbindRecord();
+        tenantUnbindRecord.setTenantId(user.getTenantId());
+        tenantUnbindRecord.setTenantName(tenantInfo == null ? "" : tenantInfo.getName());
+        tenantUnbindRecord.setUserId(user.getId());
+        tenantUnbindRecord.setUserName(user.getRealName());
+        tenantUnbindRecord.setPhone(user.getPhone());
+
+        String subjectId = teacher.getSubjectId();
+        if (StringUtils.isNotEmpty(subjectId)) {
+            List<Long> subjectIdList = Arrays.stream(subjectId.split(",")).map(Long::valueOf)
+                    .collect(Collectors.toList());
+            List<Subject> subject = subjectService.findBySubjectByIdList(subjectIdList);
+            String subjectName = subject.stream().map(Subject::getName).collect(Collectors.joining(","));
+            tenantUnbindRecord.setSubjectName(subjectName);
+        }
+
+        tenantUnbindRecord.setUserType("TEACHER");
+        tenantUnbindRecord.setUnbindReason(unbindTenant.getUnbindReason());
+        tenantUnbindRecord.setStatus(ETenantUnBindAuditStatus.DOING);
+        tenantUnbindRecordService.saveOrUpdate(tenantUnbindRecord);
+
+        if (one != null) {
+            tenantUnbindRecordService.lambdaUpdate()
+                    .set(TenantUnbindRecord::getVerifyUserId, null)
+                    .set(TenantUnbindRecord::getReason, null)
+                    .set(TenantUnbindRecord::getInterveneTime, null)
+                    .eq(TenantUnbindRecord::getId, one.getId())
+                    .update();
+        }
+        return succeed();
+    }
+
+    @PostMapping("/unbindTenantCancel")
+    @ApiOperation(value = "解绑机构申请撤销")
+    public HttpResponseResult<Boolean> unbindTenantCancel() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        boolean update = tenantUnbindRecordService.lambdaUpdate()
+                .eq(TenantUnbindRecord::getUserId, user.getId())
+                .eq(TenantUnbindRecord::getTenantId, user.getTenantId())
+                .eq(TenantUnbindRecord::getStatus, ETenantUnBindAuditStatus.DOING)
+                .set(TenantUnbindRecord::getStatus, ETenantUnBindAuditStatus.CANCEL)
+                .update();
+        if (!update) {
+            throw new BizException("未查询到提交的申请记录");
+        }
+        return succeed();
+
+    }
+}

+ 153 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherCourseGroupController.java

@@ -0,0 +1,153 @@
+package com.yonge.cooleshow.teacher.controller;
+
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
+import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.collections.MapUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * 课程组表(CourseGroup)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:10
+ */
+@Api(tags = "课程组表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseGroup")
+public class TeacherCourseGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseGroupService courseGroupService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+    @ApiOperation("直播课详情")
+    @GetMapping("/queryLiveCourseInfo")
+    public HttpResponseResult<LiveCourseInfoVo> queryLiveCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryLiveCourseInfo(groupId));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
+            @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
+            @ApiImplicitParam(name = "groupStatus", dataType = "String", value = "课程组状态  ING(进行中)  NOT_SALE(未开售,未上架) APPLY(报名中,销售中) COMPLETE(已完成) OUT_SALE(已下架)"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+            @ApiImplicitParam(name = "myself", dataType = "Boolean", value = "查看我自己的直播课"),
+            @ApiImplicitParam(name = "version", dataType = "String", value = "版本"),
+            @ApiImplicitParam(name = "platform", dataType = "Integer", value = "平台"),
+    })
+    @ApiOperation("分页查询直播课课程组列表")
+    @PostMapping("/queryPageCourseGroup")
+    public HttpResponseResult<PageInfo<CourseGroupVo>> queryPageLiveCourseGroup(@RequestBody Map<String, Object> param) {
+
+
+        Boolean myself = MapUtils.getBoolean(param,"myself");
+        if (myself == null || myself) {
+            Long teacherId = WrapperUtil.toLong(param, "teacherId");
+            teacherId = Optional.ofNullable(teacherId).orElseGet(() -> getSysUser().getId());
+            param.put("teacherId", teacherId);
+        } else {
+            YesOrNoEnum auditVersion = YesOrNoEnum.NO;
+            if (param.get("platform") != null && param.get("version") != null) {
+                auditVersion = appVersionInfoService.getAppAuditVersion(param.get("platform").toString(),param.get("version").toString());
+            }
+            param.put("auditVersion",auditVersion);
+            param.put("groupStatus","APPLY");
+
+        }
+
+
+        return succeed(courseGroupService.queryPageLiveCourseGroup(param));
+    }
+
+
+
+    @ApiOperation("创建直播课程组-新增课程组")
+    @PostMapping("/addLiveCourse")
+    public HttpResponseResult<Object> addLiveCourse(@RequestBody LiveCourseGroupDto dto) {
+        if (dto.getCoursePrice().compareTo(BigDecimal.ZERO) <= 0) {
+            return failed("课程价格不能为0元");
+        }
+        courseGroupService.addLiveCourse(dto);
+        return succeed();
+    }
+
+
+    @ApiOperation("修改直播课程组")
+    @PostMapping("/updateLiveCourse")
+    public HttpResponseResult<Object> updateLiveCourse(@RequestBody LiveCourseGroupDto dto) {
+        courseGroupService.updateLiveCourse(dto);
+        return succeed();
+    }
+
+
+    @ApiOperation("创建直播课程组-锁定课程时间-将课时写到缓存当作锁定的时间")
+    @PostMapping("/lockCourseToCache")
+    public HttpResponseResult<List<CourseTimeEntity>> lockCourseToCache(@RequestBody CheckCourseTimeDto dto) {
+        return succeed(courseGroupService.lockCourseToCache(dto));
+    }
+
+    @ApiOperation("创建直播课程组-解除锁定课程时间-删除写到缓存当作锁定的课时")
+    @GetMapping("/unlockCourseToCache")
+    public HttpResponseResult<Object> unlockCourseToCache(@RequestParam("teacherId") Long teacherId) {
+        courseGroupService.unlockCourseToCache(teacherId);
+        return succeed();
+    }
+
+    @ApiOperation("取消课程组-下架课程组")
+    @GetMapping("/cancelCourseGroup")
+    public HttpResponseResult<Object> cancelCourseGroup(@RequestParam("groupId") Long groupId) {
+        courseGroupService.cancelCourseGroup(groupId);
+        return succeed();
+    }
+
+    @ApiOperation("获取老师排直播课时锁定的课时")
+    @GetMapping("/getLockCache")
+    public HttpResponseResult<Object> getLockCache(@RequestParam("teacherId") Long teacherId) {
+        return succeed(courseGroupService.getLiveLockTimeCache(teacherId).get(teacherId));
+    }
+
+    private SysUser getSysUser() {
+        return Optional.ofNullable(sysUserFeignService.queryUserInfo())
+                .orElseThrow(() -> new BizException("用户不存在"));
+    }
+
+
+
+}
+

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

@@ -0,0 +1,318 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
+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.CourseStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomePage;
+import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 老师课程表(CourseSchedule)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:11
+ */
+@Api(tags = "老师课程表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/courseSchedule")
+public class TeacherCourseScheduleController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private HolidaysFestivalsService holidaysFestivalsService;
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "classDate", dataType = "Integer", value = "年月"),
+            @ApiImplicitParam(name = "status", dataType = "String", value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成"),
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+    })
+    @ApiOperation("老师端-首页-我的课程-直播课")
+    @PostMapping("/queryTeacherLiveCourse")
+    public HttpResponseResult<PageInfo<TeacherLiveCourseInfoVo>> queryTeacherLiveCourse(@RequestBody Map<String, Object> param) {
+        return succeed(courseScheduleService.queryTeacherLiveCourse(param));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "year", dataType = "Integer", value = "年"),
+            @ApiImplicitParam(name = "month", dataType = "Integer", value = "月"),
+            @ApiImplicitParam(name = "singleCourseMinutes", dataType = "Integer", value = "单课时时长(不包含休息时间)"),
+            @ApiImplicitParam(name = "freeCourseMinutes", dataType = "Integer", value = "单课时休息时长)"),
+            @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
+    })
+    @ApiOperation("直播课创建时的日历数据")
+    @PostMapping("/createLiveCourseCalendar")
+    public HttpResponseResult<List<CourseCalendarEntity>> createLiveCourseCalendar(@RequestBody Map<String, Object> param) {
+        return succeed(courseScheduleService.createLiveCourseCalendar(param));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
+            @ApiImplicitParam(name = "studentId", dataType = "Long", value = "学生id"),
+            @ApiImplicitParam(name = "year", dataType = "Integer", value = "年"),
+            @ApiImplicitParam(name = "month", dataType = "Integer", value = "月"),
+            @ApiImplicitParam(name = "day", dataType = "Integer", value = "日"),
+    })
+    @ApiOperation("陪练课日历-用于学生购买指定老师陪练课")
+    @PostMapping("/createPracticeCourseCalendar")
+    public HttpResponseResult<List<CourseCalendarEntity>> generatePracticeCourseCalender(@RequestBody Map<String, Object> param) {
+        return succeed(courseScheduleService.createPracticeCourseCalender(param));
+    }
+
+    @ApiOperation(value = "陪练课查询",
+            notes = "老师端-首页-我的课程-陪练课\n" +
+                    "search:{\"classMonth\":\"2022-03\",\"status\":\"COMPLETE\",\"subjectId\":1}\n" +
+                    "老师端-首页-课后评价\n" +
+                    "search:{\"classMonth\":\"2022-03\",\"replied\":0,\"studentName\":\"测试王\"}\n" +
+                    "老师端-我的-我的主页\n" +
+                    "search:{\"classMonth\":\"2022-03\"}\n" +
+                    "老师端-课表\n" +
+                    "search:{\"classDate\":\"2022-03-27\"}\n" +
+                    "     search:{\"classMonth\":\"2022-03\"}\n" +
+                    "老师端-课表-陪练课\n" +
+                    "     search:{\"classDate\":\"2022-03-27\"}")
+    @PostMapping("/queryTeacherPracticeCourse")
+    public HttpResponseResult<PageInfo<MyCourseVo>> queryTeacherPracticeCourse(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        search.setTeacherId(user.getId());
+        IPage<MyCourseVo> pages = courseScheduleService.queryTeacherPracticeCourse(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation("老师端-课表-日历")
+    @PostMapping("/queryCourseSchedule")
+    public HttpResponseResult<Set<String>> queryCourseSchedule(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        search.setTeacherId(user.getId());
+        return succeed(courseScheduleService.queryCourseSchedule(search));
+    }
+
+    @ApiOperation(value = "老师端-课表-日历-用户", notes = "search:{\"classDate\":\"2022-03-27\"}")
+    @PostMapping("/queryCourseUser")
+    public HttpResponseResult<Map<String, Object>> queryCourseUser(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        search.setTeacherId(user.getId());
+        return succeed(courseScheduleService.queryCourseUser(search));
+    }
+
+    @ApiOperation(value = "老师端-课表-日历-调课")
+    @PostMapping("/courseAdjust")
+    public HttpResponseResult<Object> courseAdjust(@Validated @RequestBody CourseAdjustVo adjustVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        courseScheduleService.courseAdjust(adjustVo, user.getId());
+        return succeed();
+    }
+
+    @ApiOperation("老师-首页-最近课程")
+    @GetMapping("/queryLiveAndVideo")
+    public HttpResponseResult<StudentHomePage> queryLiveAndVideo() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(courseScheduleService.queryLiveAndVideo(null, user.getId(), null));
+    }
+
+    @ApiOperation("老师端-查询房间配置")
+    @GetMapping("/selectRoomConfig")
+    public HttpResponseResult<Object> selectRoomConfig() {
+        return succeed(courseScheduleService.selectRoomConfig());
+    }
+
+    //测试未约满课老师
+    @GetMapping("/test")
+    public HttpResponseResult<Object> test(Integer amount) {
+//        courseScheduleService.scheduleTask();
+//        return succeed(courseScheduleService.getTeacherId(amount));
+//        courseScheduleService.scheduleTask();
+//        courseScheduleService.teacherSalaryTask();
+        courseScheduleService.scheduleTask();
+        return succeed();
+    }
+
+    @ApiOperation("查询琴房剩余时长、冻结时长、统计学员人数")
+    @GetMapping("/selectRemainTime")
+    public HttpResponseResult<PianoRoomTimeVo> selectRemainTime() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(courseScheduleService.selectRemainTime(user.getId()));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "学员声部id"),
+            @ApiImplicitParam(name = "userName", dataType = "String", value = "学员姓名"),
+            @ApiImplicitParam(name = "courseId", dataType = "Long", value = "课程id"),
+    })
+    @ApiOperation("我的学员&课内学员")
+    @PostMapping("/selectStudent")
+    public HttpResponseResult<PageInfo<CourseStudentVo>> selectStudent(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        return succeed(courseScheduleService.selectStudent(param));
+    }
+
+    @ApiOperation("排课")
+    @PostMapping("/arrangeCourse")
+    public HttpResponseResult<Object> arrangeCourse(@RequestBody ArrangeCourseVo arrangeCourseVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        courseScheduleService.arrangeCourse(arrangeCourseVo, user.getId());
+        return succeed();
+    }
+
+    @ApiOperation("根据月份查询消耗时长")
+    @GetMapping("/selectConsumeTime")
+    public HttpResponseResult<Object> selectConsumeTime(String month) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(courseScheduleService.selectConsumeTime(month, user.getId()));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "month", dataType = "String", value = "月份,yyyy-mm"),
+            @ApiImplicitParam(name = "status", dataType = "String", value = "课程状态"),
+    })
+    @ApiOperation("琴房课程列表")
+    @PostMapping("/selectCourseList")
+    public HttpResponseResult<PageInfo<CourseScheduleRecordVo>> selectCourseList(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        return succeed(courseScheduleService.selectCourseList(param));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "month", dataType = "String", value = "月份,yyyy-mm"),
+            @ApiImplicitParam(name = "status", dataType = "String", value = "课程状态"),
+    })
+    @ApiOperation("消耗时长列表")
+    @PostMapping("/selectConsumeTimeList")
+    public HttpResponseResult<PageInfo<CourseScheduleRecordVo>> selectConsumeTimeList(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        return succeed(courseScheduleService.selectConsumeTimeList(param));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "courseId", dataType = "Long", value = "课程id"),
+    })
+    @ApiOperation("删除课程")
+    @PostMapping("/deleteCourse")
+    public HttpResponseResult<Object> deleteCourse(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        courseScheduleService.deleteCourse(param);
+        return succeed();
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "courseId", dataType = "Long", value = "课程id"),
+            @ApiImplicitParam(name = "startTime", dataType = "String", value = "上课时间"),
+            @ApiImplicitParam(name = "endTime", dataType = "String", value = "下课时间"),
+    })
+    @ApiOperation("调整上课时间")
+    @PostMapping("/updateCourseTime")
+    public HttpResponseResult<Object> updateCourseTime(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        courseScheduleService.updateCourseTime(param);
+        return succeed();
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "studentIds", dataType = "List", value = "学生id集合"),
+            @ApiImplicitParam(name = "courseId", dataType = "Long", value = "课程id"),
+    })
+    @ApiOperation("调整上课学员")
+    @PostMapping("/updateCourseStudent")
+    public HttpResponseResult<Object> updateCourseStudent(@RequestBody Map<String, Object> param) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        param.put("teacherId", user.getId());
+        courseScheduleService.updateCourseStudent(param);
+        return succeed();
+    }
+
+    @ApiOperation("查询节假日")
+    @GetMapping("/selectHoliday")
+    public HttpResponseResult<Object> selectHoliday(Integer year) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(holidaysFestivalsService.queryByYear(year));
+    }
+}
+

+ 63 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherFreeTimeController.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.PracticeTimesSetting;
+import com.yonge.cooleshow.biz.dal.entity.TeacherFreeTime;
+import com.yonge.cooleshow.biz.dal.service.TeacherFreeTimeService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherFreeTimeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 老师可排课时间表(TeacherFreeTime)表控制层
+ *
+ * @author zx
+ * @since 2022-03-25 10:04:26
+ */
+@Api(tags = "老师可排课时间表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/teacherFreeTime")
+public class TeacherFreeTimeController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private TeacherFreeTimeService teacherFreeTimeService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增、修改老师陪练课设置")
+    @PostMapping("/upSet")
+    public HttpResponseResult upSet(@Valid @RequestBody TeacherFreeTime teacherFreeTime){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        teacherFreeTime.setTeacherId(user.getId());
+        teacherFreeTimeService.upSet(teacherFreeTime);
+        return succeed();
+    }
+
+    @ApiOperation(value = "获取老师陪练课设置")
+    @PostMapping("/getDetail")
+    public HttpResponseResult<TeacherFreeTimeVo> getDetail(@RequestBody PracticeTimesSetting practiceTimesSetting){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        practiceTimesSetting.setUserId(user.getId());
+        return succeed(teacherFreeTimeService.getDetail(practiceTimesSetting));
+    }
+}
+

+ 87 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherHomeController.java

@@ -0,0 +1,87 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherHomeStatisticalVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+
+/**
+ * Description 老师课后作业相关接口
+ *
+ * @author liujunchi
+ * @date 2022-04-13
+ */
+@Api(tags = "老师APP首页接口")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/home")
+public class TeacherHomeController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private UserAccountRecordService userAccountRecordService;
+
+    @ApiOperation(value = "首页统计数据")
+    @GetMapping(value="/count")
+    public HttpResponseResult<TeacherHomeStatisticalVo> countTeacherHome() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 我的课程
+        Integer courseSechedule  = courseScheduleService.getWeekNotStart(sysUser.getId());
+
+        // 课后作业
+        Integer courseHomework = courseScheduleService.getHomeworkNotDecorate(sysUser.getId());
+
+        // 课后评价
+        Integer courseScheduleReplied = courseScheduleService.getNotRepliedCourseSchedule(sysUser.getId());
+
+        // 我的乐谱
+        Integer musicSheet = musicSheetService.getTeacherMusicSheetCount(sysUser.getId());
+
+        // 我收到的评价
+        Integer studentReplied = courseScheduleService.getWeekStudentRepliedCourseSchedule(sysUser.getId());
+
+        // 我的收入
+        BigDecimal decimal = userAccountRecordService.getMonthDecimal(sysUser.getId());
+
+
+        // 琴房剩余时长
+        PianoRoomTimeVo pianoRoomTimeVo = courseScheduleService.selectRemainTime(sysUser.getId());
+
+        TeacherHomeStatisticalVo teacherHomeStatisticalVo = new TeacherHomeStatisticalVo();
+        teacherHomeStatisticalVo.setCourseHomework(courseHomework);
+        teacherHomeStatisticalVo.setCourseScheduleReplied(courseScheduleReplied);
+        teacherHomeStatisticalVo.setCourseSchedule(courseSechedule);
+        teacherHomeStatisticalVo.setDecimal(decimal);
+        teacherHomeStatisticalVo.setMusicSheet(musicSheet);
+        teacherHomeStatisticalVo.setStudentReplied(studentReplied);
+        teacherHomeStatisticalVo.setPianoTime(pianoRoomTimeVo.getRemainTime());
+        return succeed(teacherHomeStatisticalVo);
+    }
+
+
+
+}

+ 128 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomController.java

@@ -0,0 +1,128 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.entity.ImUserStateSync;
+import com.yonge.cooleshow.biz.dal.entity.LiveRoom;
+import com.yonge.cooleshow.biz.dal.entity.RoomInfoCache;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 直播房间与课程的关系表表(LiveRoom)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:41:16
+ */
+@Api(tags = "直播房间与课程的关系表表")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/liveRoom")
+public class TeacherLiveRoomController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(TeacherLiveRoomController.class);
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private LiveRoomService liveRoomService;
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "roomType", dataType = "String", value = "房间类型  LIVE-直播课  TEMP-临时直播间"),
+            @ApiImplicitParam(name = "liveState", dataType = "String", value = "直播状态 0未开始 1已开始 2已结束"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+    })
+    @ApiOperation("分页查询当前用户关联的房间信息")
+    @PostMapping("/queryPageRoom")
+    public HttpResponseResult<PageInfo<LiveRoom>> queryPageRoom(@RequestBody Map<String, Object> param) {
+        return succeed(liveRoomService.queryPageRoom(param));
+    }
+
+    /**
+     * 根据房间uid查询房间信息
+     *
+     * @param roomUid 房间uid
+     */
+    @GetMapping("/speakerCheckRoomInfo")
+    public HttpResponseResult<RoomInfoCache> speakerCheckRoomInfo(@RequestParam("roomUid") String roomUid) {
+        return succeed(liveRoomService.speakerCheckRoomInfo(roomUid));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "roomTitle", dataType = "String", value = "房间标题"),
+            @ApiImplicitParam(name = "liveRemark", dataType = "String", value = "直播内容/最多200个字"),
+            @ApiImplicitParam(name = "liveTime", dataType = "Integer", value = "直播时长"),
+            @ApiImplicitParam(name = "coverPic", dataType = "String", value = "封面图"),
+    })
+    @ApiOperation("创建临时房间-直播间")
+    @PostMapping("/createTempLiveRoom")
+    public HttpResponseResult<String> createTempLiveRoom(@RequestBody Map<String, Object> param) {
+        return succeed(liveRoomService.createTempLiveRoom(param));
+    }
+
+    @ApiOperation("同步点赞数量")
+    @GetMapping("/syncLike")
+    public HttpResponseResult<Object> syncLike(@ApiParam(value = "房间uid", required = true) String roomUid,
+                                               @ApiParam(value = "点赞数", required = true) Integer likeNum) {
+        liveRoomService.syncLike(roomUid, likeNum);
+        return succeed();
+    }
+
+    @ApiOperation("主讲人-进入房间")
+    @GetMapping(value = "/speakerJoinRoom")
+    public HttpResponseResult<RoomInfoCache> speakerJoinRoom(String roomUid) {
+        return succeed(liveRoomService.speakerJoinRoom(roomUid));
+    }
+
+
+    @ApiOperation("设置是否允许连麦")
+    @GetMapping("/whetherMic")
+    public HttpResponseResult<Object> whetherMic(@ApiParam(value = "房间uid", required = true) String roomUid,
+                                                      @ApiParam(value = "是否连麦 0:是 1否", required = true) Integer whetherMic) {
+        liveRoomService.whetherMic(roomUid,whetherMic);
+        return succeed();
+    }
+
+    @ApiOperation("手动关闭直播间")
+    @GetMapping("/destroyLiveRoom")
+    public HttpResponseResult<Object> destroyLiveRoom(@ApiParam(value = "房间uid", required = true) String roomUid) {
+        liveRoomService.destroyLiveRoom(roomUid);
+        return succeed();
+    }
+
+    /**
+     * 同步融云用户状态变更
+     *
+     * @param userState
+     */
+    @PostMapping(value = "/syncUserStatus")
+    public void statusImUser(@RequestBody List<ImUserStateSync> userState) {
+        log.info("opsRoom >>>>> : {}", JSONObject.toJSONString(userState));
+        liveRoomService.opsRoom(userState);
+    }
+
+    @ApiOperation("方便测试观察房间数据的方法")
+    @GetMapping("/test")
+    public Object destroyExpiredLiveRoom(@RequestParam("roomUid") String roomUid) {
+        return liveRoomService.test(roomUid);
+    }
+
+}
+

+ 56 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/TeacherLiveRoomVideoController.java

@@ -0,0 +1,56 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.entity.LiveRoomVideo;
+import com.yonge.cooleshow.biz.dal.entity.RecordNotify;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomVideoService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 直播视频记录(LiveRoomVideo)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:41:17
+ */
+@Api(tags = "直播视频记录")
+@RestController
+@RequestMapping("${app-config.url.teacher:}/liveRoomVideo")
+public class TeacherLiveRoomVideoController extends BaseController {
+
+    private final static Logger log = LoggerFactory.getLogger(TeacherLiveRoomVideoController.class);
+
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private LiveRoomVideoService liveRoomVideoService;
+
+    @ApiOperation("查询直播回放")
+    @GetMapping("/queryVideo")
+    public HttpResponseResult<List<LiveRoomVideo>> queryVideo(@ApiParam(value = "房间uid", required = true) String roomUid) {
+        return succeed(liveRoomVideoService.queryVideo(roomUid));
+    }
+
+    @ApiOperation("录制结果回调")
+    @RequestMapping(value = "/recordSync")
+    public void recordSync(@RequestBody String body) {
+        log.info("recordSync body:{}", body);
+        RecordNotify recordNotify = JSONObject.parseObject(body, RecordNotify.class);
+        liveRoomVideoService.recordSync(recordNotify);
+    }
+
+}
+

+ 80 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UploadFileController.java

@@ -0,0 +1,80 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.microsvc.toolkit.middleware.oss.wrapper.OssWrapper;
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.entity.UploadReturnBean;
+import com.yonge.toolset.thirdparty.entity.UploadSign;
+import com.yonge.toolset.utils.upload.UploadUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 上传控制层
+ */
+@RestController
+@Api(tags = "文件上传服务")
+@RequestMapping("${app-config.url.teacher:}")
+public class UploadFileController extends BaseController {
+
+    private final static Logger LOGGER = LoggerFactory.getLogger(UploadFileController.class);
+
+    @Autowired
+    private UploadFileService uploadFileService;
+
+    @PostMapping("/uploadFile")
+    public Object uploadFile(@ApiParam(value = "上传的文件", required = true) @RequestParam("file") MultipartFile file) {
+        try {
+            if (file != null && StringUtils.isNotBlank(file.getOriginalFilename())) {
+                UploadReturnBean bean = uploadFileService.uploadFile(file.getInputStream(), UploadUtil.getExtension(file.getOriginalFilename()));
+                bean.setName(file.getOriginalFilename());
+                if (bean.isStatus()) {
+                    return succeed(bean);
+                }
+                return failed(bean.getMessage());
+            }
+        } catch (Exception e) {
+            LOGGER.error("上传失败", e);
+        }
+        return failed("上传失败");
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bucketName", dataType = "String", value = "为空时默认使用daya"),
+            @ApiImplicitParam(name = "fileName", dataType = "String", value = "要上传的文件名称,不包含路径信息"),
+            @ApiImplicitParam(name = "postData", dataType = "Map", value = "1.如果使用js sdk上传的时候设置了ACL请设置,例\"acl\":\"public-read\"值要与SDK中一致,没有则删除该项</br>" +
+                    "2.提供js sdk中的key值,例\"key\":\"20150115/中文/${filename}\""),
+            @ApiImplicitParam(name = "unknowValueField", dataType = "List", value = "对于用户无法确定表单值的放在unknownValueField中(比如有的上传控件会添加一些表单项,但表单项的值可能是随机的)"),
+            @ApiImplicitParam(name = "pluginName", dataType = "String", value = "插件名称,默认ks3,可选值:ks3,aliyun,tencent"),
+    })
+    @ApiOperation(value = "获取上传文件签名", notes = "{\n" +
+            "    \"bucketName\":\"\",\n" +
+            "    \"filename\":\"test.png\",\n" +
+            "    \"postData\":{\n" +
+            "        \"acl\":\"public-read\",\n" +
+            "        \"key\":\"20150115/中文/${filename}\"\n" +
+            "    },\n" +
+            "    \"unknowValueField\":[\"test\"]\n" +
+            "}")
+    @PostMapping("/getUploadSign")
+    public HttpResponseResult<OssWrapper.ResponseSign> getUploadSign(@RequestParam(defaultValue = "ks3") String pluginName,
+                                                                     @RequestBody UploadSign uploadSign) {
+        // 设置默认文件存储服务方
+        uploadSign.setPluginName(pluginName);
+        return succeed(uploadFileService.getUploadSign(uploadSign));
+    }
+}

+ 143 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserAccountController.java

@@ -0,0 +1,143 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.TotalReq;
+import com.yonge.cooleshow.biz.dal.dto.search.UserAccountRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
+import com.yonge.cooleshow.biz.dal.service.UserAccountService;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
+import com.yonge.cooleshow.biz.dal.vo.res.AccountShareTotal;
+import com.yonge.cooleshow.biz.dal.vo.res.AccountTotal;
+import com.yonge.cooleshow.common.controller.BaseController;
+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.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.date.DateUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userAccount")
+@Api(value = "用户账户表", tags = "用户账户表")
+public class UserAccountController extends BaseController {
+    @Autowired
+    private UserAccountService userAccountService;
+    @Autowired
+    private UserAccountRecordService userAccountRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	/**
+     * 查询单条
+     */
+    @GetMapping("/detail")
+    @ApiOperation(value = "详情")
+    public HttpResponseResult<UserAccountVo> detail() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+    	return succeed(userAccountService.detail(user.getId()));
+	}
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入userAccountRecordSearch")
+    public HttpResponseResult<PageInfo<UserAccountRecordVo>> page(@RequestBody UserAccountRecordSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+
+        if (StringUtil.isEmpty(query.getSearchDate())) {
+            query.setSearchDate(DateUtil.format(new Date(), "yyyy-MM"));
+        }
+        String[] classDateSp = query.getSearchDate().split("-");
+        try {
+            LocalDate date = LocalDate.of(Integer.parseInt(classDateSp[0]), Integer.parseInt(classDateSp[1]), 1);
+
+            LocalDateTime firstDay = LocalDateTime.of(date.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+            LocalDateTime lastDay = LocalDateTime.of(date.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+
+            query.setStartTime(firstDay);
+            query.setEndTime(lastDay);
+        } catch (Exception e) {
+            throw new BizException("查询时间格式不正确 [" + query.getSearchDate() + "]");
+        }
+
+        IPage<UserAccountRecordVo> pages = userAccountRecordService.appSelectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "收入数据统计")
+    @PostMapping("/accountTotal")
+    public HttpResponseResult<AccountTotal> accountTotal(@Valid @RequestBody TotalReq query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        return userAccountService.accountTotal(query);
+    }
+
+    @ApiOperation(value = "酷乐秀推广计划-统计")
+    @PostMapping("/accountShareTotal")
+    public HttpResponseResult<AccountShareTotal> accountShareTotal() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TotalReq query = new TotalReq();
+        query.setUserId(user.getId());
+        return userAccountService.accountShareTotal(query);
+    }
+
+    @PostMapping("/sharePage")
+    @ApiOperation(value = "酷乐秀推广计划-分页", notes = "传入userAccountRecordSearch")
+    public HttpResponseResult<PageInfo<UserAccountRecordVo>> sharePage(@RequestBody UserAccountRecordSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        if (StringUtil.isEmpty(query.getSearchDate())) {
+            query.setSearchDate(DateUtil.format(new Date(), "yyyy-MM"));
+        }
+        String[] classDateSp = query.getSearchDate().split("-");
+        try {
+            LocalDate date = LocalDate.of(Integer.parseInt(classDateSp[0]), Integer.parseInt(classDateSp[1]), 1);
+
+            LocalDateTime firstDay = LocalDateTime.of(date.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+            LocalDateTime lastDay = LocalDateTime.of(date.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+
+            query.setStartTime(firstDay);
+            query.setEndTime(lastDay);
+        } catch (Exception e) {
+            throw new BizException("查询时间格式不正确 [" + query.getSearchDate() + "]");
+        }
+        IPage<UserAccountRecordVo> pages = userAccountRecordService.sharePage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 119 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserBankCardController.java

@@ -0,0 +1,119 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.UserBankCardDto;
+import com.yonge.cooleshow.biz.dal.dto.search.UserBankCardSearch;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.entity.UserBankCard;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.UserBankCardService;
+import com.yonge.cooleshow.biz.dal.vo.UserBankCardVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.exception.ThirdpartyException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userBankCard")
+@Api(value = "用户绑卡记录表", tags = "用户绑卡记录表")
+public class UserBankCardController extends BaseController {
+    @Autowired
+    private UserBankCardService userBankCardService;
+	@Autowired
+	private SysUserFeignService sysUserFeignService;
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	@PostMapping("/bankList")
+	@ApiOperation(value = "查询银行")
+	public HttpResponseResult<List<SysConfig>> bankList() {
+		Map<String,Object> params = new HashMap<>();
+		params.put("group", "BANK");
+		List<SysConfig> configs = sysConfigService.findAll(params);
+		return succeed(configs);
+	}
+
+	/**
+	 * 查询分页
+	 */
+	@PostMapping("/page")
+	@ApiOperation(value = "查询分页", notes = "传入userBankCardSearch")
+	public HttpResponseResult<PageInfo<UserBankCardVo>> page(@RequestBody UserBankCardSearch query) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		query.setUserId(user.getId());
+
+		IPage<UserBankCardVo> pages = userBankCardService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+	@PostMapping("/bankCard")
+	@ApiOperation(value = "用户绑卡")
+	public HttpResponseResult<UserBankCard> bankCard(@Valid @RequestBody UserBankCardDto bankCard) {
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		bankCard.setUserId(user.getId());
+		try {
+			return userBankCardService.bankCard(bankCard);
+		}catch (ThirdpartyException e){
+			return HttpResponseResult.failed(e.getMessage());
+		}catch (BizException e){
+			return HttpResponseResult.failed(e.getMessage());
+		}catch (Exception e){
+			return HttpResponseResult.failed("绑卡失败");
+		}
+	}
+
+	@PostMapping("/unBind")
+	@ApiOperation(value = "用户解绑银行卡")
+	@ApiImplicitParams({
+			@ApiImplicitParam(name = "id", value = "银行卡id", paramType = "query", dataType = "long"),
+			@ApiImplicitParam(name = "name", value = "真实姓名", paramType = "query", dataType = "String"),
+			@ApiImplicitParam(name = "idCardNo", value = "身份证号码", paramType = "query", dataType = "String"),
+	})
+	public HttpResponseResult<UserBankCard> unBind(@ApiIgnore @RequestBody UserBankCardDto bankCard) {
+		if(null == bankCard.getId() || StringUtil.isEmpty(bankCard.getIdCardNo()) || StringUtil.isEmpty(bankCard.getName())){
+			return HttpResponseResult.failed("缺少参数");
+		}
+		SysUser user = sysUserFeignService.queryUserInfo();
+		if (user == null || null == user.getId()) {
+			return failed(HttpStatus.FORBIDDEN, "请登录");
+		}
+		bankCard.setUserId(user.getId());
+		try {
+			return userBankCardService.unBind(bankCard);
+		}catch (ThirdpartyException e){
+			return HttpResponseResult.failed(e.getMessage());
+		}catch (BizException e){
+			return HttpResponseResult.failed(e.getMessage());
+		}catch (Exception e){
+			return HttpResponseResult.failed("解绑失败");
+		}
+	}
+
+}

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

@@ -0,0 +1,339 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.OrderPayReq;
+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.UserOrder;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderVo;
+import com.yonge.cooleshow.biz.dal.vo.res.OrderPayRes;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.cooleshow.common.enums.EPaymentVersion;
+import com.yonge.cooleshow.teacher.vo.UserPaymentOrderVo;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.payment.base.enums.PaymentClientEnum;
+import com.yonge.toolset.payment.util.DistributedLock;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.web.WebUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/3/11 18:16
+ */
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userOrder")
+@Api(value = "订单接口", tags = "订单接口")
+public class UserOrderController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(UserOrderController.class);
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private UserOrderService userOrderService;
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
+    @ApiOperation(value = "下单接口")
+    @PostMapping("/executeOrder")
+    public HttpResponseResult<UserOrder> executeOrder(@Valid @RequestBody OrderReq orderReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        orderReq.setUserId(user.getId());
+        orderReq.setOrderClient(ClientEnum.TEACHER);
+        try {
+            HttpResponseResult<UserOrder> res = DistributedLock.of(redissonClient)
+                    .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
+                            , userOrderService::executeOrder, orderReq, 10L);
+            if (null != res) {
+                return res;
+            } else {
+                return HttpResponseResult.failed("下单失败");
+            }
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("下单失败");
+        }
+    }
+
+    @ApiOperation(value = "订单下单付款")
+    @PostMapping("/orderPay")
+    public HttpResponseResult<OrderPayRes> orderPay(@Valid @RequestBody OrderPayReq payReq, HttpServletRequest request) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(payReq.getOrderNo())) {
+            return failed("订单号不能为空");
+        }
+        payReq.setPaymentClient(PaymentClientEnum.TEACHER);
+        payReq.setUserId(user.getId());
+        payReq.setIpAddress(WebUtil.getRemoteIp(request));
+
+        try {
+            HttpResponseResult<OrderPayRes> res = DistributedLock.of(redissonClient)
+                    .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(user.getId())
+                            , userOrderService::orderPay, payReq, 10L);
+            if (null != res) {
+                return res;
+            } else {
+                return HttpResponseResult.failed("付款失败");
+            }
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("付款失败");
+        }
+    }
+
+    @ApiOperation(value = "取消订单")
+    @PostMapping("/orderCancel")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderNo", value = "订单号", paramType = "query", dataType = "String", required = true),
+            @ApiImplicitParam(name = "reason", value = "取消说明", paramType = "query", dataType = "String")
+    })
+    public HttpResponseResult<Boolean> orderCancel(@ApiIgnore @RequestBody OrderPayReq payReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(payReq.getOrderNo())) {
+            return failed("订单号不能为空");
+        }
+        payReq.setUserId(user.getId());
+
+        UserOrder order = userOrderService.getByOrderNo(payReq.getOrderNo());
+        if (null == order) {
+            return failed("订单不存在");
+        }
+        if(order.getPaymentVersion().equals(EPaymentVersion.V2)){
+
+
+            // 用户取消支付
+            userPaymentCoreService.cancelPayment(JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.STUDENT.getCode()).build(), payReq.getOrderNo());
+        } else {
+
+            try {
+                HttpResponseResult<Boolean> res = DistributedLock.of(redissonClient)
+                        .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(payReq.getOrderNo())
+                                , userOrderService::orderCancel, payReq, 10L);
+                if (null != res) {
+                    return res;
+                } else {
+                    return HttpResponseResult.failed("取消订单失败");
+                }
+            } catch (BizException e) {
+                return HttpResponseResult.failed(e.getMessage());
+            } catch (Exception e) {
+                e.printStackTrace();
+                return HttpResponseResult.failed("取消订单失败");
+            }
+        }
+        return succeed();
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入orderSearch")
+    public HttpResponseResult<PageInfo<UserOrderVo>> page(@RequestBody OrderSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        query.setOrderClient(ClientEnum.TEACHER.getCode());
+        if (StringUtil.isEmpty(query.getSearchDate())) {
+            query.setSearchDate(DateUtil.format(new Date(), "yyyy-MM"));
+        }
+        String[] classDateSp = query.getSearchDate().split("-");
+        try {
+            LocalDate date = LocalDate.of(Integer.parseInt(classDateSp[0]), Integer.parseInt(classDateSp[1]), 1);
+
+            LocalDateTime firstDay = LocalDateTime.of(date.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+            LocalDateTime lastDay = LocalDateTime.of(date.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+
+            query.setStartTime(firstDay);
+            query.setEndTime(lastDay);
+        } catch (Exception e) {
+            throw new BizException("查询时间格式不正确 [" + query.getSearchDate() + "]");
+        }
+        IPage<UserOrderVo> pages = userOrderService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "通过id查询详情", notes = "传入id")
+    public HttpResponseResult<UserOrderVo> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        UserOrder param = new UserOrder();
+        param.setUserId(user.getId());
+        param.setId(id);
+        UserOrderVo detail = userOrderService.detailApp(param);
+        return succeed(detail);
+    }
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detailByOrderNo/{orderNo}")
+    @ApiOperation(value = "通过订单号查询详情", notes = "传入orderNo")
+    public HttpResponseResult<UserOrderVo> detailByOrderNo(@PathVariable("orderNo") String orderNo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        UserOrder param = new UserOrder();
+        param.setUserId(user.getId());
+        param.setOrderNo(orderNo);
+        UserOrderVo detail = userOrderService.detailApp(param);
+        return succeed(detail);
+    }
+
+
+    @ApiOperation(value = "用户下单", notes = "用户下单")
+    @PostMapping("/executeOrder/v2")
+    public R<UserPaymentOrderWrapper.PaymentConfig> executeOrderV2(@Validated @RequestBody UserPaymentOrderVo.OrderReq orderReq) {
+
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("用户信息不存在");
+        }
+        orderReq.setUserId(sysUser.getId());
+        orderReq.setPaymentClient(ClientEnum.TEACHER.name());
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.UserPaymentOrder order = JSON.parseObject(orderReq.jsonString(), UserPaymentOrderWrapper.UserPaymentOrder.class);
+
+        // 新增数据
+        UserPaymentOrderWrapper.PaymentConfig paymentConfig = userPaymentCoreService.executeOrderCreate(order);
+        if (Objects.isNull(paymentConfig)) {
+            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("下单失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment/v2")
+    public R<UserPaymentOrderWrapper.PaymentReq> executePaymentV2(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config,HttpServletRequest request) {
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("用户信息不存在");
+        }
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
+
+        reqConfig.setIp(ServletUtil.getClientIP(request));
+        // 创建用户支付数据
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(sysUser.getId().toString()).clientType(ClientEnum.TEACHER.getCode()).build(), reqConfig);
+        if (Objects.isNull(paymentConfig)) {
+            throw com.microsvc.toolkit.common.webportal.exception.BizException.from("付款失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+    @ApiOperation(value = "取消订单")
+    @PostMapping("/orderCancel/v2")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderNo", value = "订单号", paramType = "query", dataType = "String", required = true),
+            @ApiImplicitParam(name = "reason", value = "取消说明", paramType = "query", dataType = "String")
+    })
+    public HttpResponseResult<Boolean> orderCancelV2(@ApiIgnore @RequestBody OrderPayReq payReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(payReq.getOrderNo())) {
+            return failed("订单号不能为空");
+        }
+        payReq.setUserId(user.getId());
+
+        // 用户取消支付
+        userPaymentCoreService.cancelPayment(JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.TEACHER.getCode()).build(), payReq.getOrderNo());
+
+        return HttpResponseResult.status(true);
+    }
+
+
+    @ApiOperation(value = "检测订单应该使用哪种支付方式")
+    @PostMapping("/orderPayType")
+    public HttpResponseResult<UserPaymentOrderWrapper.OrderPayTypeResp> orderPayType( @RequestBody UserPaymentOrderWrapper.OrderPayTypeReq payTypeReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        payTypeReq.setBuyId(user.getId());
+        payTypeReq.setClientType(ClientEnum.TEACHER);
+
+        return HttpResponseResult.succeed(userPaymentCoreService.orderPayType(payTypeReq));
+    }
+
+
+}

+ 130 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserWithdrawalController.java

@@ -0,0 +1,130 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.WithdrawalReq;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherWithdrawalSearch;
+import com.yonge.cooleshow.biz.dal.service.UserWithdrawalService;
+import com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo;
+import com.yonge.cooleshow.biz.dal.vo.res.WithdrawalInfoRes;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.payment.util.DistributedLock;
+import com.yonge.toolset.utils.date.DateUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.validation.Valid;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.temporal.TemporalAdjusters;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userWithdrawal")
+@Api(value = "用户账户结算表", tags = "用户账户结算表")
+public class UserWithdrawalController extends BaseController {
+
+    @Autowired
+    private UserWithdrawalService userWithdrawalService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @PostMapping("/getWithdrawalInfo")
+    @ApiOperation(value = "查询结算页面信息")
+    public HttpResponseResult<WithdrawalInfoRes> getWithdrawalInfo() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return userWithdrawalService.getWithdrawalInfo(user.getId());
+    }
+
+    @PostMapping("/withdrawal")
+    @ApiOperation(value = "用户结算")
+    public HttpResponseResult<Boolean> withdrawal(@Valid @RequestBody WithdrawalReq withdrawalReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        try {
+            HttpResponseResult<Boolean> res = DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_WITHDRAWAL.getRedisKey(user.getId())
+                            , () -> userWithdrawalService.withdrawal(user, withdrawalReq), 60L, TimeUnit.SECONDS);
+            if(null != res){
+                return res;
+            }else{
+                return HttpResponseResult.failed("结算失败");
+            }
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        }  catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("结算失败");
+        }
+    }
+
+
+    @PostMapping("/withdrawalPage")
+    @ApiOperation(value = "结算记录")
+    @ApiImplicitParams({
+            @ApiImplicitParam(
+                    name = "status",
+                    value = "状态 DOING、审核中 PASS、通过 UNPASS、不通过",
+                    paramType = "query", dataType = "String"
+            ),
+            @ApiImplicitParam(
+                    name = "searchDate",
+                    value = "查询时间(yyyy-mm)",
+                    paramType = "query", dataType = "String"
+            )
+    })
+    public HttpResponseResult<PageInfo<UserWithdrawalVo>> withdrawalPage(@ApiIgnore @RequestBody TeacherWithdrawalSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+
+        if (StringUtil.isEmpty(query.getSearchDate())) {
+            query.setSearchDate(DateUtil.format(new Date(), "yyyy-MM"));
+        }
+        String[] classDateSp = query.getSearchDate().split("-");
+        try {
+            LocalDate date = LocalDate.of(Integer.parseInt(classDateSp[0]), Integer.parseInt(classDateSp[1]), 1);
+
+            LocalDateTime firstDay = LocalDateTime.of(date.with(TemporalAdjusters.firstDayOfMonth()), LocalTime.MIN);
+            LocalDateTime lastDay = LocalDateTime.of(date.with(TemporalAdjusters.lastDayOfMonth()), LocalTime.MAX);
+
+            query.setStartTime(firstDay);
+            query.setEndTime(lastDay);
+        } catch (Exception e) {
+            throw new BizException("查询时间格式不正确 [" + query.getSearchDate() + "]");
+        }
+
+        IPage<UserWithdrawalVo> pages = userWithdrawalService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 225 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupController.java

@@ -0,0 +1,225 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonGroupSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.valid.AddGroup;
+import com.yonge.cooleshow.biz.dal.valid.UpdateGroup;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupUpVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonShelvesVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * 视频课基本信息表 web 控制层
+ *
+ * @author yzp
+ * @version v1.0
+ * @date 2022-03-26 00:21:46
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/videoLessonGroup")
+@Api(tags = "视频课组")
+public class VideoLessonGroupController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private VideoLessonGroupService videoLessonGroupService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    /**
+     * @Description: 查询视频课组
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "查询视频课组")
+    @PostMapping(value = "/page")
+    public HttpResponseResult<PageInfo<VideoLessonGroupVo>> page(@RequestBody VideoLessonGroupSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (query.getMyself() == null || query.getMyself()) {
+            query.setTeacherId(sysUser.getId());
+        } else {
+            // 检查app版本
+            query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(), query.getVersion()));
+        }
+        if (query.getMyself() != null && !query.getMyself()) {
+            query.setAuditStatus(AuthStatusEnum.PASS.getCode());
+        }
+        IPage<VideoLessonGroupVo> pages = videoLessonGroupService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * @Description: 新增视频课组
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "新增视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/create", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> create(@Validated @RequestBody VideoLessonGroup videoLessonGroup) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroup.setTeacherId(sysUser.getId());
+        videoLessonGroupService.save(videoLessonGroup);
+        return succeed();
+    }
+
+    /**
+     * @Description: 修改视频课组
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "修改视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/updateGroup", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated @RequestBody VideoLessonGroupUpVo lessonGroupUpVo) {
+        videoLessonGroupService.updateGroup(lessonGroupUpVo);
+        return succeed();
+    }
+
+    /**
+     * @Description: 删除视频课组
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "删除视频课组", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        videoLessonGroupService.deleteGroup(id);
+        return succeed();
+    }
+
+    /**
+     * @Description: 新增视频课组&视频课
+     * @Author: cy
+     * @Date: 2022/4/1
+     */
+    @ApiOperation(value = "新增视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/add", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> add(@Validated(AddGroup.class) @RequestBody VideoLessonVo lessonVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        lessonVo.setUserBy(sysUser.getId());
+        if (CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        lessonVo.getLessonGroup().setDraftFlag(YesOrNoEnum.NO);
+        videoLessonGroupService.add(lessonVo, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 根据组id查询视频课&视频课组
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "根据组id查询视频课&视频课组")
+    @GetMapping(value = "/selectVideoLesson")
+    public HttpResponseResult<VideoLessonStudentVo> selectVideoLesson(@NotNull(message = "视频组id不能为空") Long groupId) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        VideoLessonStudentVo videoLessonStudentVo = videoLessonGroupService.selectVideoLesson(groupId);
+        if (videoLessonStudentVo.getLessonGroup().getTeacherId().equals(sysUser.getId())) {
+            videoLessonStudentVo.setMyself(true);
+        } else {
+            videoLessonStudentVo.setMyself(false);
+        }
+        if (videoLessonStudentVo.getLessonGroup() != null && sysUser.getId().equals(videoLessonStudentVo.getLessonGroup().getId())) {
+            videoLessonStudentVo.setAlreadyBuy(true);
+        } else {
+            videoLessonStudentVo.setAlreadyBuy(false);
+        }
+        return succeed(videoLessonStudentVo);
+    }
+
+    /**
+     * @Description: 更新上架状态
+     * @Author: cy
+     * @Date: 2022/4/25
+     */
+    @ApiOperation(value = "更新上架状态", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/updateShelves", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> updateShelves(@Validated @RequestBody VideoLessonShelvesVo shelvesVo) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (shelvesVo.getShelvesFlag() != 0) {
+            return failed("只能做下架操作");
+        }
+        /*if (shelvesVo.getShelvesFlag() == 0 && StringUtil.isEmpty(shelvesVo.getShelvesReason())) {
+            return failed("下架必须要有下架原因");
+        }*/
+
+        shelvesVo.setShelvesId(user.getId());
+        shelvesVo.setShelvesTime(new Date());
+
+        shelvesVo.setClientType(ClientEnum.TEACHER);
+        videoLessonGroupService.updateShelves(shelvesVo);
+        return succeed();
+    }
+
+    /**
+     * @Description: 修改视频课组&视频课
+     * @Author: cy
+     * @Date: 2022/4/7
+     */
+    @ApiOperation(value = "修改视频课组&视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/update", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated(UpdateGroup.class) @RequestBody VideoLessonVo lessonVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        lessonVo.setUserBy(sysUser.getId());
+        if (CollectionUtils.isEmpty(lessonVo.getLessonList())) {
+            return failed("课程不能为空");
+        }
+        lessonVo.getLessonGroup().setDraftFlag(YesOrNoEnum.NO);
+        return succeed(videoLessonGroupService.update(lessonVo, sysUser));
+    }
+
+
+}

+ 148 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VideoLessonGroupDetailController.java

@@ -0,0 +1,148 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.VideoLessonGroupDetailDto;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonEvaluateSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonEvaluate;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonEvaluateService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupDetailService;
+import com.yonge.cooleshow.biz.dal.valid.impl.ValidList;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonEvaluateVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupDetailUpVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonGroupDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonPurchaseStudent;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 视频课明细表 web 控制层
+ *
+ * @author yzp
+ * @version v1.0
+ * @date 2022-03-26 00:21:46
+ **/
+@RestController
+@RequestMapping("${app-config.url.teacher:}/videoLesson")
+@Api(tags = "视频课")
+public class VideoLessonGroupDetailController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private VideoLessonEvaluateService evaluateService;
+
+    @Autowired
+    private VideoLessonGroupDetailService videoLessonGroupDetailService;
+
+    /**
+     * @Description: 查询视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "查询视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/page", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonGroupDetailVo>> page(@RequestBody VideoLessonSearch query) {
+        IPage<VideoLessonGroupDetailVo> pages = videoLessonGroupDetailService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * @Description: 根据组id查询购买用户
+     * @Author: cy
+     * @Date: 2022/4/1
+     */
+    @ApiOperation(value = "根据组id查询购买用户", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/pageStudent", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<PageInfo<VideoLessonPurchaseStudent>> pageStudent(@RequestBody VideoLessonSearch query) {
+        IPage<VideoLessonPurchaseStudent> pages = videoLessonGroupDetailService.selectPageStudent(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * @Description: 新增视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "新增视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/create", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> create(@Validated @RequestBody ValidList<VideoLessonGroupDetailDto> videoLessonList) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroupDetailService.insertVideoLesson(videoLessonList, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 修改视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "修改视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/update", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> update(@Validated @RequestBody VideoLessonGroupDetailUpVo detailUpVo) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        videoLessonGroupDetailService.updateDetail(detailUpVo, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 删除视频课
+     * @Author: cy
+     * @Date: 2022/3/31
+     */
+    @ApiOperation(value = "删除视频课", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping("/delete/{id}")
+    public Object delete(@PathVariable Long id) {
+        videoLessonGroupDetailService.deleteDetail(id);
+        return succeed();
+    }
+
+    /**
+     * @Description: 视频课评价
+     * @Author: cy
+     * @Date: 2022/4/8
+     */
+    @ApiOperation(value = "视频课评价", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/evaluate", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Object> evaluate(@Validated @RequestBody VideoLessonEvaluate evaluate) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+
+        evaluateService.evaluate(evaluate, sysUser);
+        return succeed();
+    }
+
+    /**
+     * @Description: 根据视频id查评论
+     * @Author: cy
+     * @Date: 2022/4/11
+     */
+    @ApiOperation(value = "根据视频id查评论")
+    @PostMapping(value = "/page")
+    public HttpResponseResult<PageInfo<VideoLessonEvaluateVo>> selectEvaluate(@RequestBody VideoLessonEvaluateSearch query) {
+        IPage<VideoLessonEvaluateVo> pages = evaluateService.selectEvaluate(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 61 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/VipCardRecordController.java

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.VipCardRecordSearch;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.biz.dal.vo.VipCardRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/vipCardRecord")
+@Api(value = "购买会员卡记录表", tags = "购买会员卡记录表")
+public class VipCardRecordController extends BaseController {
+
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{orderDetilId}")
+    @ApiOperation(value = "详情", notes = "传入订单详情id")
+    public HttpResponseResult<VipCardRecordVo> detail(@PathVariable("orderDetilId") Long orderDetilId) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(vipCardRecordService.detail(orderDetilId, user.getId()));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入vipCardRecordSearch")
+    public HttpResponseResult<PageInfo<VipCardRecordVo>> page(@RequestBody VipCardRecordSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        IPage<VipCardRecordVo> pages = vipCardRecordService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

+ 108 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/coupon/CouponInfoController.java

@@ -0,0 +1,108 @@
+package com.yonge.cooleshow.teacher.controller.coupon;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponInfoQuery;
+import com.yonge.cooleshow.biz.dal.queryInfo.CouponIssueQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.CouponIssueService;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponInfoWrapper;
+import com.yonge.cooleshow.biz.dal.vo.coupon.CouponIssueWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.teacher.io.request.CouponInfoVO;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+@RestController
+@RequestMapping("${app-config.url.teacher:}/couponInfo")
+@Api(value = "优惠券信息", tags = "优惠券信息")
+public class CouponInfoController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private CouponIssueService couponIssueService;
+
+    /**
+     * 优惠券信息
+     * @param request CouponInfoVO.RequestInfo
+     * @return HttpResponseResult<PageInfo<CouponInfoVO.ResponseInfo>>
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询优惠券分页", notes = "传入CouponInfoVO.PageRequest")
+    public HttpResponseResult<PageInfo<CouponInfoVO.CouponPageInfo>> queryCouponPageInfo(@RequestBody CouponInfoVO.PageRequest request) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        request.setUserId(user.getId());
+        request.setClientType(ClientEnum.TEACHER.getCode());
+
+        // 用户端的券类型 都包含全品类券
+        if (request.getCouponCategory() != null) {
+            List<CouponCategoryEnum> couponCategoryList = new ArrayList<>();
+            couponCategoryList.add(CouponCategoryEnum.UNIVERSAL);
+            couponCategoryList.add(request.getCouponCategory());
+            request.setCouponCategory(null);
+            request.setCouponCategoryList(couponCategoryList);
+        }
+
+        IPage<CouponIssueWrapper> couponIssueWrapperIPage = couponIssueService.queryCouponIssueInfo(
+                PageUtil.getPage(request), CouponIssueQueryInfo.from(request.jsonString()));
+
+
+        // 数据转换
+        List<CouponInfoVO.CouponPageInfo> pageInfos = JSON.parseArray(JSON.toJSONString(couponIssueWrapperIPage.getRecords()),
+                                                                      CouponInfoVO.CouponPageInfo.class);
+
+        return succeed(PageUtil.getPageInfo(couponIssueWrapperIPage,pageInfos));
+    }
+
+    /**
+     * 优惠券状态统计信息
+     * @return List<CouponInfoVO.CouponIssueStateStat>
+     */
+    @GetMapping("/statInfo")
+    @ApiOperation(value = "查询优惠券统计")
+    public HttpResponseResult<List<CouponInfoVO.CouponStateStat>> findCouponStateStatInfo(
+            @ApiParam(value = "优惠券类型") @RequestParam(value = "couponType", required = false) String couponType) {
+
+        // 登录用户信息
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(user) || Objects.isNull(user.getId())) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        List<CouponInfoWrapper.CouponStat> wrappers = couponIssueService.queryCouponStateStatInfo(user.getId(),
+                CouponInfoQuery.CouponStateStatQuery.builder()
+                .clientType(ClientEnum.TEACHER)
+                .build().couponType(couponType));
+
+        return succeed(JSON.parseArray(JSON.toJSONString(wrappers), CouponInfoVO.CouponStateStat.class));
+    }
+}

+ 199 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenShareController.java

@@ -0,0 +1,199 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicImgDto;
+import com.yonge.cooleshow.biz.dal.dto.search.ShareProfitParam;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.vo.CheckVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
+import com.yonge.cooleshow.biz.dal.vo.ShareProfitVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open")
+@Api(tags = "开放权限接口-分享")
+public class OpenShareController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(OpenShareController.class);
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private VideoLessonGroupService videoLessonGroupService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+    @Autowired
+    private SysConfigService sysConfigService;
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private MusicAlbumService musicAlbumService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+
+    @ApiOperation(value = "新增曲谱渲染图")
+    @PostMapping(value="/music/sheet/img")
+    public HttpResponseResult<Boolean> img(@RequestBody @Valid MusicImgDto musicImgDto) {
+        return succeed(musicSheetService.updateMusicImg(musicImgDto, musicImgDto.getMusicSheetId()));
+    }
+
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseGroupService courseGroupService;
+
+    @ApiOperation(value = "老师乐谱分享分润")
+    @PostMapping(value="/musicShareProfit")
+    public HttpResponseResult<ShareProfitVo> shareMusicSheetProfit(@RequestBody @Valid ShareProfitParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserById(param.getUserId());
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(musicSheetService.shareMusicSheetProfit(sysUser,param.getBizId()));
+    }
+
+    @ApiOperation(value = "老师专辑分享分润")
+    @PostMapping(value="/albumShareProfit")
+    public HttpResponseResult<ShareProfitVo> albumShareProfit(@RequestBody @Valid  ShareProfitParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserById(param.getUserId());
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(musicAlbumService.albumShareProfit(sysUser,param.getBizId()));
+    }
+
+    @ApiOperation(value = "老师直播课分享分润")
+    @PostMapping(value= "/liveShareProfit")
+    public HttpResponseResult<ShareProfitVo> shareLiveCourseProfit(@RequestBody @Valid  ShareProfitParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserById(param.getUserId());
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(courseGroupService.shareLiveCourseProfit(sysUser, param.getBizId()));
+    }
+
+
+
+    @ApiOperation(value = "老师视频课分享分润")
+    @PostMapping(value= "/videoShareProfit")
+    public HttpResponseResult<ShareProfitVo> shareVideoCourseProfit(@RequestBody @Valid  ShareProfitParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserById(param.getUserId());
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(videoLessonGroupService.shareVideoCourseProfit(sysUser, param.getBizId()));
+    }
+
+
+
+    @ApiOperation(value = "老师VIP分享分润")
+    @PostMapping(value="/vipProfit")
+    public HttpResponseResult<ShareProfitVo> shareVipProfit(@RequestBody ShareProfitParam param) {
+        SysUser sysUser = sysUserFeignService.queryUserById(param.getUserId());
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        return succeed(memberPriceSettingsService.shareVipProfit(sysUser,param.getBizId()));
+    }
+
+    @ApiOperation(value = "老师活动分享", notes = "活动id")
+    @PostMapping(value = "/activity/info/{id}")
+    public HttpResponseResult<MusicActivityVo> getDetail(@PathVariable Long id) {
+        // SysUser user = sysUserFeignService.queryUserInfo();
+
+        MusicActivityVo activityVo = activityPlanService.getActivityInfo(id, null);
+
+        return succeed(activityVo);
+    }
+
+
+    @ApiOperation(value = "检查活动状态", notes = "活动id")
+    @PostMapping(value = "/activity/state/{id}")
+    public HttpResponseResult<CheckVo> state(@PathVariable Long id) {
+        // SysUser user = sysUserFeignService.queryUserInfo();
+
+        YesOrNoEnum state = activityPlanService.state(id);
+
+        CheckVo checkVo = new CheckVo();
+        checkVo.setCheck(state);
+        return succeed(checkVo);
+    }
+
+
+    @PostMapping("/memberPriceSettings/vipPermissions")
+    @ApiOperation(value = "查询vip权限")
+    public HttpResponseResult<List<SysConfig>> vipPermissions() {
+        Map<String,Object> params = new HashMap<>();
+        params.put("group", "VIP_PERMISSION");
+        List<SysConfig> configs = sysConfigService.findAll(params);
+        return succeed(configs);
+    }
+
+    @ApiOperation(value = "用户老师身份查询")
+    @GetMapping("/teacher/identity/{ID}")
+    public HttpResponseResult<Boolean> userTeacherIdentityInfo(@PathVariable("ID") Long userId) {
+
+        // 校验请求参数
+        if (Optional.ofNullable(userId).orElse(0L) <= 0) {
+            return succeed(false);
+        }
+
+        // 根据用户ID,查询老师身份信息
+        Teacher teacher = teacherService.getOne(Wrappers.<Teacher>lambdaQuery().eq(Teacher::getUserId, userId));
+
+        // 响应数据
+        return succeed(Objects.nonNull(teacher));
+    }
+
+    @PostMapping("/appVersion")
+    @ApiOperation(value = "查询app是否为审核版本")
+    public HttpResponseResult<CheckVo> appVersion(@RequestBody Map<String,String> obj) {
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(obj.get("platform"), obj.get("version"));
+        CheckVo checkVo = new CheckVo();
+        checkVo.setCheck(appAuditVersion);
+        return succeed(checkVo);
+    }
+}

+ 53 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/UserPaymentClient.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.teacher.vo.UserPaymentOrderVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+@Slf4j
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/userOrder")
+@Api(tags = "开放权限接口-支付回调")
+public class UserPaymentClient {
+
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment/v2")
+    public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config, HttpServletRequest request) {
+        // 设置下单用户信息
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
+
+        reqConfig.setIp(ServletUtil.getClientIP(request));
+        // 创建用户支付数据
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(config.getUserId()).clientType(ClientEnum.TENANT.getCode()).build(), reqConfig);
+        if (Objects.isNull(paymentConfig)) {
+            throw BizException.from("付款失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+}

+ 110 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/UserWithdrawalClient.java

@@ -0,0 +1,110 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.entity.UserWithdrawalCallback;
+import com.yonge.cooleshow.biz.dal.enums.DealStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.UserWithdrawalService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.thirdparty.lingxinpay.RSA;
+import com.yonge.toolset.utils.json.JsonUtil;
+import io.swagger.annotations.Api;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/userWithdrawal")
+@Api(value = "开放权限接口-结算", hidden = true)
+public class UserWithdrawalClient extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(UserWithdrawalClient.class);
+
+    @Autowired
+    private UserWithdrawalService userWithdrawalService;
+
+    @Value("${withdraw.privateKey}")
+    private String privateKey;
+
+    /**
+     * 异步回调接收-结算
+     *
+     * @param content
+     * @param request
+     * @return
+     */
+    @PostMapping("/callback")
+    public String callback(@RequestBody String content, HttpServletRequest request) {
+        log.info("交易回调请求地址:{} 请求参数:{}", request.getRemoteAddr(), content);
+        try {
+            if (StringUtils.isBlank(content)) {
+                throw new Exception();
+            }
+            JSONObject jsonObject = JSONObject.parseObject(content);
+            String jsonStr = RSA.decryptPri(jsonObject.getString("sign"), privateKey);
+            log.info("jsonStr:{}", jsonStr);
+
+            Map<String, Object> withdrawRecord = JSONObject.parseObject(jsonStr);
+            UserWithdrawalCallback callback = JsonUtil.toJavaObject(withdrawRecord, UserWithdrawalCallback.class);
+
+            userWithdrawalService.callback(callback, jsonStr);
+        } catch (BizException e) {
+            log.error("解密失败e:{}", e.getMessage());
+            return "failed";
+        } catch (Exception e) {
+            log.error("解密失败e:{}", e);
+            return "failed";
+        }
+        return "success";
+    }
+
+    /**
+     * 异步回调接收-签署协议
+     *
+     * @param dataStr
+     * @param request
+     * @return
+     */
+    @PostMapping("/contractCallback")
+    public String contractCallback(@RequestBody String dataStr, HttpServletRequest request) {
+        log.info("回调请求地址:{} 请求参数:{}", request.getRemoteAddr(), dataStr);
+        try {
+            if (StringUtils.isBlank(dataStr)) {
+                throw new Exception();
+            }
+            JSONObject data = JSONObject.parseObject(dataStr);
+            JSONObject content = data.getJSONObject("content");
+
+            String return_code = data.getString("return_code");
+
+            if (CollectionUtils.isEmpty(content) || null == content.getString("serialNo")) {
+                log.error("签署失败,返回合同编号为空 {}", dataStr);
+                return "failed";
+            }
+
+            if ("T".equals(return_code)) {
+                userWithdrawalService.contractCallback(
+                        DealStatusEnum.SUCCESS.getCode(), content.getString("serialNo"),
+                        content.getString("contractUrl"), null);
+                return "success";
+            } else {
+                String return_message = data.getString("return_message");
+                userWithdrawalService.contractCallback(
+                        DealStatusEnum.FAILED.getCode(), content.getString("serialNo"), null, return_message);
+                return "failed";
+            }
+        } catch (Exception e) {
+            log.error("签署失败e:{}", e);
+            return "failed";
+        }
+    }
+}

+ 136 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/io/request/ActivityVo.java

@@ -0,0 +1,136 @@
+package com.yonge.cooleshow.teacher.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.common.enums.RewardTypeEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.Date;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-10-09
+ */
+public class ActivityVo {
+
+    @ApiModel("ReceiveRewardQuery-活动领取奖品查询")
+    public static class ReceiveRewardQuery extends QueryInfo {
+
+        // 用户id
+        @ApiModelProperty(hidden = true)
+        private Long userId;
+
+        // 客户端类型
+        @ApiModelProperty(hidden = true)
+        private ClientEnum client;
+
+
+        // 是否领取
+        @ApiModelProperty("是否已领取,1是 2:否")
+        private YesOrNoEnum receive;
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public Long getUserId() {
+            return userId;
+        }
+
+        public void setUserId(Long userId) {
+            this.userId = userId;
+        }
+
+        public ClientEnum getClient() {
+            return client;
+        }
+
+        public void setClient(ClientEnum client) {
+            this.client = client;
+        }
+
+        public YesOrNoEnum getReceive() {
+            return receive;
+        }
+
+        public void setReceive(YesOrNoEnum receive) {
+            this.receive = receive;
+        }
+    }
+
+    @ApiModel("ReceiveRewardList-活动领取奖品列表")
+    public static class ReceiveRewardList {
+
+        @ApiModelProperty("领奖id")
+        private Long receiveRewardId;
+
+        @ApiModelProperty("奖品名称 ")
+        private String rewardName;
+
+        @ApiModelProperty("奖品类型:  ACTUAL 实物 VIP 小酷AI会员 PIANO_ROOM 琴房时长 COUPON(优惠券)")
+        private RewardTypeEnum rewardType;
+
+        @ApiModelProperty("奖品描述 ")
+        private String rewardDescribe;
+
+        @ApiModelProperty("奖品图片 ")
+        private String imgUrl;
+
+        @ApiModelProperty("获奖时间")
+        private Date winningTime;
+
+        public Long getReceiveRewardId() {
+            return receiveRewardId;
+        }
+
+        public void setReceiveRewardId(Long receiveRewardId) {
+            this.receiveRewardId = receiveRewardId;
+        }
+
+        public String getRewardName() {
+            return rewardName;
+        }
+
+        public void setRewardName(String rewardName) {
+            this.rewardName = rewardName;
+        }
+
+        public RewardTypeEnum getRewardType() {
+            return rewardType;
+        }
+
+        public void setRewardType(RewardTypeEnum rewardType) {
+            this.rewardType = rewardType;
+        }
+
+        public String getRewardDescribe() {
+            return rewardDescribe;
+        }
+
+        public void setRewardDescribe(String rewardDescribe) {
+            this.rewardDescribe = rewardDescribe;
+        }
+
+        public String getImgUrl() {
+            return imgUrl;
+        }
+
+        public void setImgUrl(String imgUrl) {
+            this.imgUrl = imgUrl;
+        }
+
+        public Date getWinningTime() {
+            return winningTime;
+        }
+
+        public void setWinningTime(Date winningTime) {
+            this.winningTime = winningTime;
+        }
+    }
+}

+ 137 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/io/request/CouponInfoVO.java

@@ -0,0 +1,137 @@
+package com.yonge.cooleshow.teacher.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.annotation.JSONField;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponCategoryEnum;
+import com.yonge.cooleshow.biz.dal.enums.coupon.CouponUseStateEnum;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.List;
+
+/**
+ * 优惠券信息
+ * Created by Eric.Shang on 2022/9/2.
+ */
+public class CouponInfoVO {
+
+    /**
+     * 优惠券分页请求信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页请求", description = "优惠券信息分页")
+    public static class PageRequest extends QueryInfo {
+
+        @ApiModelProperty(value = "用户id",hidden = true)
+        private Long userId;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用状态 USED:已使用 USABLE:未使用 EXPIRED:过期  WITHDRAW 撤回")
+        private String useState;
+
+
+        @ApiModelProperty("可用品类 UNIVERSAL:全场通用 VIP:小酷Ai PIANO:云酷琴房 MALL:商场购物券 MUSIC:单曲点播券 SPARRING:陪练课购买券 LIVE:直播课购买券  VIDEO:视频课购买券")
+        private CouponCategoryEnum couponCategory;
+
+        @ApiModelProperty("订单金额")
+        private BigDecimal amount;
+
+        @ApiModelProperty("是否订单使用,0:否 1:是")
+        private Integer orderUse;
+
+        // 可用品类
+        @ApiModelProperty(hidden = true)
+        private List<CouponCategoryEnum> couponCategoryList;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    /**
+     * 优惠券分页响应数据
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(value = "优惠券信息分页信息", description = "优惠券信息分页信息")
+    public static class CouponPageInfo implements Serializable {
+
+        @ApiModelProperty("优惠券发放id")
+        private Long couponIssueId;
+
+        @ApiModelProperty("优惠券名称")
+        private String couponName;
+
+        @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
+        private String clientType;
+
+        @ApiModelProperty("优惠券类型: FULL_DISCOUNT(满减券) VOUCHER(代金券) ")
+        private String couponType;
+
+        @ApiModelProperty("使用门槛")
+        private BigDecimal useLimit;
+
+        @ApiModelProperty("优惠金额")
+        private BigDecimal discountPrice;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("优惠券ID")
+        private Long couponId;
+
+        @ApiModelProperty("使用状态: EXPIRED(已失效) USABLE(可使用) USED(已使用) ")
+        private CouponUseStateEnum useState;
+
+        @ApiModelProperty("使用时间")
+        private Long useTime;
+
+        @ApiModelProperty("生效时间")
+        @JSONField(format = "yyyy-MM-dd")
+        private Long startTime;
+
+        @ApiModelProperty("失效时间")
+        @JSONField(format = "yyyy-MM-dd")
+        private Long endTime;
+
+        @ApiModelProperty("能使用的")
+        private Integer usable;
+
+
+        @ApiModelProperty("可用品类 UNIVERSAL:全场通用 VIP:小酷Ai PIANO:云酷琴房 MALL:商场购物券 MUSIC:单曲点播券 SPARRING:陪练课购买券 LIVE:直播课购买券  VIDEO:视频课购买券")
+        private CouponCategoryEnum couponCategory;
+
+    }
+
+    /**
+     * 优惠券发放状态统计
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class CouponStateStat implements Serializable {
+
+        @ApiModelProperty("使用状态 USED:已使用 USABLE:未使用 EXPIRED:过期")
+        private CouponUseStateEnum useState;
+
+        @ApiModelProperty("数量统计")
+        private Integer total;
+
+    }
+}

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/task/TaskController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.teacher.task;
+
+import com.yonge.cooleshow.biz.dal.entity.TeacherTotal;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.service.TeacherTotalService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.List;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/3/28 15:50
+ */
+@RestController
+@RequestMapping("/task")
+@ApiIgnore
+public class TaskController extends BaseController {
+    @Autowired
+    private TeacherTotalService teacherTotalService;
+    @Autowired
+    private CourseGroupService courseGroupService;
+    @Autowired
+    private CourseScheduleService scheduleService;
+    @Autowired
+    private LiveRoomService liveRoomService;
+
+
+    /***
+     * 查询所有老师统计数据
+     * @author liweifan
+     * @updateTime 2022/3/28 10:12
+     * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.util.List < com.yonge.cooleshow.biz.dal.vo.TeacherTotalVo>>
+     */
+    @GetMapping("/queryTeacherTotal")
+    public HttpResponseResult<List<TeacherTotal>> queryTeacherTotal() {
+        return succeed(teacherTotalService.queryTeacherTotal());
+    }
+
+    /**
+     * <p>定时将符合开售日期的未开售的直播课课程组修改为报名中状态-每隔10分钟执行一次
+     * <p>定时将符合结束售卖日期的在售卖中的直播课课程组修改为取消或者成课状态状态-每隔10分钟执行一次
+     */
+    @GetMapping("/opsCourseGroup")
+    public HttpResponseResult<Object> opsCourseGroup() {
+        courseGroupService.opsCourseGroup();
+        return HttpResponseResult.succeed();
+    }
+
+    @ApiOperation("定时任务-销毁房间-直播间")
+    @GetMapping("/destroyExpiredLiveRoom")
+    public void destroyExpiredLiveRoom() {
+        liveRoomService.destroyExpiredLiveRoom();
+    }
+
+    @ApiOperation("定时任务-创建房间-直播间")
+    @GetMapping("/createCourseLiveRoom")
+    public void createCourseLiveRoom() {
+        liveRoomService.createCourseLiveRoom();
+    }
+
+    @GetMapping("/getRedisValueByKey")
+    public HttpResponseResult<Object> getRedisValueByKey(String key) {
+        return succeed(teacherTotalService.getRedisValueByKey(key));
+    }
+
+    @GetMapping("/courseRemind")
+    public HttpResponseResult<Object> courseRemind() {
+        scheduleService.courseRemind();
+        return HttpResponseResult.succeed();
+    }
+
+    @GetMapping("/courseStatus")
+    public HttpResponseResult<Object> courseStatus() {
+        scheduleService.scheduleTask();
+        return HttpResponseResult.succeed();
+    }
+
+    @GetMapping("/teacherSalary")
+    public HttpResponseResult<Object> teacherSalary() {
+        scheduleService.teacherSalaryTask();
+        return HttpResponseResult.succeed();
+    }
+}

+ 232 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/vo/UserPaymentOrderVo.java

@@ -0,0 +1,232 @@
+package com.yonge.cooleshow.teacher.vo;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 平台订单表
+ * 2022-12-20 19:09:34
+ */
+@ApiModel(value = "UserPaymentOrderVo对象", description = "平台订单表查询视图对象")
+public class UserPaymentOrderVo {
+
+    @Data
+    @ApiModel(" UserPaymentOrder-平台订单表")
+    public static class UserPaymentOrder {
+
+
+		@ApiModelProperty("主键")
+        private Long id;
+
+		@ApiModelProperty("支付厂商")
+        private String paymentVender;
+
+		@ApiModelProperty("支付渠道")
+        private String paymentChannel;
+
+		@ApiModelProperty("用户身份")
+        private String paymentClient;
+
+		@ApiModelProperty("用户编号")
+        private Long userId;
+
+		@ApiModelProperty("商户订单号")
+        private String orderNo;
+
+		@ApiModelProperty("交易流水号")
+        private String transNo;
+
+		@ApiModelProperty("业务类型Id")
+        private String bizId;
+
+		@ApiModelProperty("订单支付类型")
+        private String orderType;
+
+		@ApiModelProperty("订单状态")
+        private String status;
+
+		@ApiModelProperty("原价")
+        private BigDecimal originalPrice;
+
+		@ApiModelProperty("现价")
+        private BigDecimal currentPrice;
+
+		@ApiModelProperty("支付现金金额")
+        private BigDecimal paymentCashAmount;
+
+		@ApiModelProperty("支付优惠金额")
+        private BigDecimal paymentCouponAmount;
+
+		@ApiModelProperty("支付通道费用")
+        private BigDecimal paymentChannelFee;
+
+		@ApiModelProperty("订单名称")
+        private String orderName;
+
+		@ApiModelProperty("订单描述信息")
+        private String orderDesc;
+
+		@ApiModelProperty("用户备注")
+        private String userNote;
+
+		@ApiModelProperty("支付时间")
+        private Date payTime;
+
+		@ApiModelProperty("原因")
+        private String errorMsg;
+
+		@ApiModelProperty("收货地址")
+        private Long receiveAddress;
+
+		@ApiModelProperty("更新时间")
+        private Date updateTime;
+
+		@ApiModelProperty("下单时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserPaymentOrder from(String json) {
+            return JSON.parseObject(json, UserPaymentOrder.class);
+        }
+
+
+        public UserPaymentOrder userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+
+        public UserPaymentOrder paymentClient(String paymentClient) {
+            this.paymentClient = String.valueOf(paymentClient);
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("下单请求对象")
+    public static class OrderReq implements Serializable {
+
+        @ApiModelProperty("支付类型: adapay")
+        private String paymentType;
+
+        @ApiModelProperty("业务类型Id")
+        private String bizId;
+
+        @NotNull(message = "订单类型不能为空")
+        @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
+        private OrderTypeEnum orderType;
+
+        @ApiModelProperty("现价")
+        private BigDecimal currentPrice;
+
+        @ApiModelProperty("支付现金金额")
+        private BigDecimal paymentCashAmount;
+
+        @ApiModelProperty("支付优惠金额")
+        private BigDecimal paymentCouponAmount;
+
+        @ApiModelProperty("订单名称")
+        private String orderName;
+
+        @ApiModelProperty("订单描述信息")
+        private String orderDesc;
+
+        @ApiModelProperty("用户备注")
+        private String userNote;
+
+        @ApiModelProperty("优惠券Id;多个使用,隔开")
+        private String couponIds;
+
+        @ApiModelProperty("订单商品信息")
+        private List<UserPaymentOrderWrapper.OrderGoodsInfo> goodsInfos;
+
+        @ApiModelProperty(value = "用户身份", hidden = true)
+        private String paymentClient;
+
+        @ApiModelProperty(value = "用户编号", hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
+        private Long recomUserId;
+
+        @ApiModelProperty(value = "活动id")
+        private Long activityId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public OrderReq paymentClient(String paymentClient) {
+            this.paymentClient = String.valueOf(paymentClient);
+            return this;
+        }
+
+        public OrderReq userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("订单支付参数配置")
+    public static class PaymentReqConfig implements Serializable {
+
+        @ApiModelProperty("支付渠道")
+        private String paymentChannel;
+
+        @ApiModelProperty("商户订单号")
+        private String merOrderNo;
+
+        @ApiModelProperty("商品名称")
+        private String subject;
+
+        @ApiModelProperty("商品描述")
+        private String body;
+
+        @ApiModelProperty("附加信息")
+        private String addition;
+
+        @ApiModelProperty("价格")
+        private BigDecimal price;
+
+        @ApiModelProperty("银行卡类型")
+        private String bankType;
+
+        @ApiModelProperty("微信授权code")
+        private String code;
+
+        @ApiModelProperty("订单过期时间")
+        private Date expirationTime;
+
+        @ApiModelProperty("微信支付公众号")
+        private String wxAppId;
+
+        @ApiModelProperty(value = "支付用户Id", hidden = true)
+        private String userId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+}

+ 155 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/IndexController.java

@@ -0,0 +1,155 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.PaymentDivMemberRecordService;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.biz.dal.service.TenantPersonStatService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantPersonStatWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Objects;
+
+@Api(tags = "首页统计")
+@RequestMapping("${app-config.url.tenant:}/index")
+@RestController
+public class IndexController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+    @Autowired
+    private TenantPersonStatService tenantPersonStatService;
+    @Autowired
+    private PaymentDivMemberRecordService paymentDivMemberRecordService;
+    @Autowired
+    private UserOrderService userOrderService;
+
+
+    @ApiOperation("学员训练数据统计列表")
+    @PostMapping("queryStudentTrainData")
+    public HttpResponseResult<PageInfo<SysMusicCompareRecordQueryInfo.WechatCompareRecordPageDto>> queryStudentTrainData
+            (@RequestBody SysMusicCompareRecordQueryInfo.WechatCompareRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        if(StringUtils.isEmpty(queryInfo.getStartTime())){
+            throw new BizException("请选择筛选时间");
+        }
+        queryInfo.setTenantId(sysUser.getTenantId());
+        return succeed(sysMusicCompareRecordService.weChatStudentTrainData(queryInfo));
+    }
+
+
+    @ApiOperation("首页学员训练数据统计列表、汇总")
+    @PostMapping("studentTrainData")
+    public HttpResponseResult<SysMusicCompareRecordQueryInfo.WechatCompareRecordDto> studentTrainData
+            (@RequestBody SysMusicCompareRecordQueryInfo.WechatCompareRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        if(StringUtils.isEmpty(queryInfo.getStartTime())){
+            throw new BizException("请选择筛选时间");
+        }
+        queryInfo.setTenantId(sysUser.getTenantId());
+        queryInfo.setRows(10);
+        SysMusicCompareRecordQueryInfo.WechatCompareRecordDto result = new SysMusicCompareRecordQueryInfo.WechatCompareRecordDto();
+        SysMusicCompareRecordQueryInfo.WechatCompareRecordSumDto sumDto = sysMusicCompareRecordService.getDao().wechatCompareRecordSum(queryInfo);
+        if(Objects.nonNull(sumDto)){
+            if(sumDto.getStudentNum() > 0){
+                if(sumDto.getTrainDays() > 0){
+                    sumDto.setAvgTrainDays(sumDto.getTrainDays() / sumDto.getStudentNum());
+                }
+                if(sumDto.getTrainTimes() > 0){
+                    sumDto.setAvgTrainTimes(sumDto.getTrainTimes() / sumDto.getStudentNum());
+                }
+            }
+        }
+        result.setSumDto(sumDto);
+        result.setPage(sysMusicCompareRecordService.weChatStudentTrainData(queryInfo).getRows());
+        return succeed(result);
+    }
+
+    @ApiOperation("机构人数统计列表")
+    @PostMapping("tenantPersonStatSum")
+    public HttpResponseResult<TenantPersonStatWrapper.TenantPersonStatSum> tenantPersonStatSum
+            (@RequestBody TenantPersonStatWrapper.TenantPersonStatQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(tenantPersonStatService.indexSum(query));
+    }
+
+    @ApiOperation("收入、支出汇总")
+    @PostMapping("incomeSummary")
+    public HttpResponseResult<PaymentDivMemberRecordWrapper.IndexIncomeSummaryDto>
+    incomeSummary(@RequestBody PaymentDivMemberRecordWrapper.IndexIncomeQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(paymentDivMemberRecordService.incomeSummary(query));
+    }
+
+    @ApiOperation("收入明细列表")
+    @PostMapping("queryIncome")
+    public HttpResponseResult<PageInfo<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto>>
+        queryIncome(@RequestBody PaymentDivMemberRecordWrapper.IndexIncomeQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(PageUtil.pageInfo(paymentDivMemberRecordService.queryIncome(QueryInfo.getPage(query), query)));
+    }
+
+    @ApiOperation("收入订单详情")
+    @PostMapping("getIncomeOrderDetail")
+    public HttpResponseResult<PaymentDivMemberRecordWrapper.OrderDetailDto> getIncomeOrderDetail(String orderNo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        return succeed(paymentDivMemberRecordService.getIncomeOrderDetail(orderNo,sysUser.getTenantId()));
+    }
+
+    @ApiOperation("支出明细列表")
+    @PostMapping("queryExpend")
+    public HttpResponseResult<PageInfo<PaymentDivMemberRecordWrapper.IndexIncomeQueryDto>>
+    queryExpend(@RequestBody PaymentDivMemberRecordWrapper.IndexIncomeQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(PageUtil.pageInfo(userOrderService.queryExpend(QueryInfo.getPage(query), query)));
+    }
+
+    @ApiOperation("支出订单详情")
+    @PostMapping("getExpendOrderDetail")
+    public HttpResponseResult<PaymentDivMemberRecordWrapper.OrderDetailDto> getExpendOrderDetail(String orderNo){
+        return succeed(userOrderService.getExpendOrderDetail(orderNo));
+    }
+}

+ 80 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/PaymentDivMemberRecordController.java

@@ -0,0 +1,80 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.entity.PaymentDivMemberRecord;
+import com.yonge.cooleshow.biz.dal.service.PaymentDivMemberRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.PaymentDivMemberRecordWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/paymentDivMemberRecord")
+@Api(tags = "分账子账户记录表")
+public class PaymentDivMemberRecordController {
+
+    @Autowired
+    private PaymentDivMemberRecordService paymentDivMemberRecordService;
+
+	@ApiOperation(value = "详情", notes = "分账子账户记录表-根据详情ID查询单条, 传入id")
+//    @PreAuthorize("@auditsvc.hasPermissions('paymentDivMemberRecord/detail', {'BACKEND'})")
+    //@GetMapping("/detail/{id}")
+    public R<PaymentDivMemberRecord> detail(@PathVariable("id") Long id) {
+    
+    	PaymentDivMemberRecord wrapper = paymentDivMemberRecordService.detail(id);
+        
+        return R.from(wrapper);
+	}
+    
+    @ApiOperation(value = "查询分页", notes = "分账子账户记录表- 传入 PaymentDivMemberRecordWrapper.PaymentDivMemberRecordQuery") 
+//    @PreAuthorize("@auditsvc.hasPermissions('paymentDivMemberRecord/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public R<PageInfo<PaymentDivMemberRecord>> page(@RequestBody PaymentDivMemberRecordWrapper.PaymentDivMemberRecordQuery query) {
+        
+        IPage<PaymentDivMemberRecord> pages = paymentDivMemberRecordService.selectPage(QueryInfo.getPage(query), query);
+        
+        return R.from(QueryInfo.pageInfo(pages));
+	}
+    
+    @ApiOperation(value = "新增", notes = "分账子账户记录表- 传入 PaymentDivMemberRecordWrapper.PaymentDivMemberRecord")
+//    @PreAuthorize("@auditsvc.hasPermissions('paymentDivMemberRecord/save', {'BACKEND'})")
+	//@PostMapping("/save")
+	public R<JSONObject> add(@Validated @RequestBody PaymentDivMemberRecord paymentDivMemberRecord) {
+        
+        // 新增数据
+        paymentDivMemberRecordService.save(paymentDivMemberRecord);
+        
+        return R.defaultR();
+	}
+    
+    @ApiOperation(value = "修改", notes = "分账子账户记录表- 传入 PaymentDivMemberRecordWrapper.PaymentDivMemberRecord")
+//    @PreAuthorize("@auditsvc.hasPermissions('paymentDivMemberRecord/update', {'BACKEND'})")
+	public R<JSONObject> update(@Validated @RequestBody PaymentDivMemberRecord paymentDivMemberRecord) {
+        
+        // 更新数据
+        paymentDivMemberRecordService.updateById(paymentDivMemberRecord);
+        
+        return R.defaultR();
+	}
+
+	@ApiOperation(value = "删除", notes = "分账子账户记录表- 传入id")
+//    @PreAuthorize("@auditsvc.hasPermissions('paymentDivMemberRecord/remove', {'BACKEND'})")
+	public R<Boolean> remove(@RequestParam Long id) {
+    
+		return R.from(paymentDivMemberRecordService.removeById(id));
+	}
+}

+ 176 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/StudentController.java

@@ -0,0 +1,176 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentSearch;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.BizHttpStatus;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+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.mybatis.support.PageUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("${app-config.url.tenant:}/student")
+@Api(value = "学生表", tags = "学生表")
+public class StudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private TenantActivationCodeService tenantActivationCodeService;
+
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<StudentVo> detail(@PathVariable("id") Long id) {
+        StudentVo detail = studentService.detail(id);
+        return succeed(detail);
+    }
+
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入StudentSearch")
+    public HttpResponseResult<PageInfo<StudentVo>> page(@RequestBody StudentSearch query) {
+        TenantInfo tenantInfo = getTenantInfo();
+        query.setTenantId(tenantInfo.getId());
+        query.setDelFlag(YesOrNoEnum.NO);
+        query.setOrderBy("u.username_ asc");
+
+        IPage<StudentVo> pages = studentService.selectPage(PageUtil.getPage(query), query);
+        List<StudentVo> rows = pages.getRecords();
+
+        Map<Long, List<TenantActivationCode>> groupByUserId = new HashMap<>();
+        if (!rows.isEmpty() && query.getTenantAlbumPurchaseId() != null) {
+            List<Long> studentIdList = rows.stream().map(Student::getUserId).collect(Collectors.toList());
+             groupByUserId = tenantActivationCodeService.lambdaQuery()
+                    .eq(TenantActivationCode::getId, query.getTenantAlbumPurchaseId())
+                    .in(TenantActivationCode::getActivationUserId, studentIdList)
+                    .list().stream().collect(Collectors.groupingBy(TenantActivationCode::getActivationUserId));
+        }
+
+        for (StudentVo vo : rows) {
+            vo.setSendActiveCodeNum(groupByUserId.getOrDefault(vo.getUserId(), new ArrayList<>()).size());
+            if (StringUtils.isNotEmpty(vo.getPhone())) {
+                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
+            }
+            if (vo.getDelFlag() == YesOrNoEnum.YES) {
+                vo.setUserStatus(UserStatusEnum.CLOSED);
+            } else {
+                if (vo.getLockFlag() == UserLockFlag.LOCKED) {
+                    vo.setUserStatus(UserStatusEnum.LOCKED);
+                } else {
+                    vo.setUserStatus(UserStatusEnum.NORMAL);
+                }
+            }
+        }
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @PostMapping("/save")
+    @ApiOperation(value = "新增/修改", notes = "传入Student")
+    public HttpResponseResult<Boolean> save(
+            @Validated @RequestBody com.yonge.cooleshow.tenant.vo.StudentVo.Student student) {
+        StudentWrapper.Student studentInfo = JSON.parseObject(JSON.toJSONString(student), StudentWrapper.Student.class);
+        TenantInfo tenantInfo = getTenantInfo();
+        studentInfo.setTenantId(tenantInfo.getId());
+
+        Long studentId = student.getId();
+
+        if (studentId == null) {
+            SysUser sysUser = sysUserFeignService.queryUserByMobile(student.getPhone());
+            if (sysUser != null) {
+                studentId = sysUser.getId();
+            }
+        }
+
+        if (studentId != null) {
+            Student one = studentService.lambdaQuery()
+                    .eq(Student::getUserId, studentId)
+                    .eq(Student::getHideFlag, 0)
+                    .last("limit 1").one();
+            if (one != null) {
+                if (one.getTenantId().equals(-1L)) {
+                    throw new BizException("该手机号已经注册为平台学生");
+                } else if (!one.getTenantId().equals(tenantInfo.getId())) {
+                    throw new BizException("该手机号已经注册为其他平台学生");
+                }
+            }
+        }
+
+        studentService.save(studentInfo);
+        return succeed();
+    }
+
+    @PostMapping("/importExcel")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importExcel(@RequestParam("file") MultipartFile file) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        try {
+            ExcelDataReader<StudentWrapper.StudentImport> reader =
+                    ExcelUtils.getReader(StudentWrapper.StudentImport.class, file);
+            studentService.importStudentExcel(reader.getDataList(), user.getTenantId(), user.getId());
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
+    private TenantInfo getTenantInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+        return tenantInfo;
+    }
+}

+ 128 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/SysAreaController.java

@@ -0,0 +1,128 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.biz.dal.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.tenant.io.request.SysAreaVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/sysArea")
+@Api(tags = "区域表")
+public class SysAreaController {
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+	/**
+	 * 查询单条
+	 * @param id 详情ID
+	 * @return R<SysAreaVo.SysArea>
+	 */
+	@ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<SysAreaWrapper.SysArea> detail(@PathVariable("id") Long id) {
+
+        return HttpResponseResult.succeed(sysAreaService.detail(id));
+	}
+
+	/**
+	 * 根据code查询
+	 * @param code 详情ID
+	 * @return R<SysAreaVo.SysArea>
+	 */
+	@ApiOperation(value = "根据code查询", notes = "传入code")
+    @GetMapping("/queryByCode/{code}")
+    public HttpResponseResult<SysArea> queryByCode(@PathVariable("code") Integer code) {
+
+		List<Integer> codeList = new ArrayList<Integer>();
+		codeList.add(code);
+		List<SysArea> list = sysAreaService.queryByCodes(codeList);
+
+		if(list == null || list.size() == 0){
+			throw BizException.from("根据code查询区域表失败");
+		}
+
+        return HttpResponseResult.succeed(list.get(0));
+	}
+
+    /**
+	 * 查询分页
+	 * @param query SysAreaVo.SysAreaQuery
+	 * @return R<PageInfo<SysAreaVo.SysAreaList>>
+	 */
+    @ApiOperation(value = "查询分页", notes = "传入sysAreaSearch")
+//    @PreAuthorize("@auditsvc.hasPermissions('sysArea/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<SysAreaWrapper.SysArea>> page(@RequestBody SysAreaWrapper.SysAreaQuery query) {
+
+        IPage<SysAreaWrapper.SysArea> pages = sysAreaService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+	}
+
+    /**
+     * 查询全部区域
+     * @return R<List<SysAreaVo.Province>>
+     */
+    @ApiOperation(value = "查询全部区域", notes = "查询全部区域")
+    @GetMapping("/queryAllProvince")
+    public HttpResponseResult<List<SysAreaVo.Province>> queryAllProvince() {
+
+        List<SysAreaVo.Province> provinces = Lists.newArrayList();
+
+        // 全部城市信息
+        Map<Integer, List<SysArea>> areaMap = sysAreaService.lambdaQuery().list().stream()
+            .filter(x -> x.getDelFlag().equals("0"))
+            .collect(Collectors.groupingBy(SysArea::getParentOrganId));
+
+        SysAreaVo.Province provinceVo;
+        SysAreaVo.City cityVo;
+        for (SysArea province : areaMap.get(0)) {
+
+            provinceVo = JSON.parseObject(JSON.toJSONString(province), SysAreaVo.Province.class)
+                .cities(Lists.newArrayList());
+            provinces.add(provinceVo);
+
+            // 城市信息
+            for (SysArea city : areaMap.get(province.getId())) {
+
+                cityVo = JSON.parseObject(JSON.toJSONString(city), SysAreaVo.City.class);
+                provinceVo.getAreas().add(cityVo);
+
+                if (areaMap.containsKey(city.getId())) {
+                    cityVo.setAreas(JSON.parseArray(JSON.toJSONString(areaMap.get(city.getId())), SysAreaVo.District.class));
+                }
+            }
+        }
+
+        return HttpResponseResult.succeed(provinces);
+    }
+}

+ 76 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/SysMusicCompareRecordController.java

@@ -0,0 +1,76 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "学生端训练记录")
+@RequestMapping("${app-config.url.tenant:}/studentMusicCompareRecord")
+@RestController
+public class SysMusicCompareRecordController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+
+    @ApiOperation("学生端学员评测记录")
+    @PostMapping("queryStudentTrain")
+    public HttpResponseResult<PageInfo<SysMusicCompareRecordQueryInfo.StudentMusicCompareRecord>>
+    queryStudentTrain(SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setUserId(sysUser.getId());
+        return succeed(sysMusicCompareRecordService.queryStudentTrain(query));
+    }
+
+    @ApiOperation("学员训练统计以及基本信息查询")
+    @PostMapping("studentTrainStat")
+    public HttpResponseResult<SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordDto>
+    studentTrainStat(SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setUserId(sysUser.getId());
+        return succeed(sysMusicCompareRecordService.studentTrainStat(query));
+    }
+
+    @ApiOperation("云教练排行榜")
+    @GetMapping("rankingList")
+    public HttpResponseResult<SysMusicCompareRecordQueryInfo.StatDto> rankingList(SysMusicCompareRecordQueryInfo.StudentCompareRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        queryInfo.setUserId(sysUser.getId());
+        queryInfo.setTenantId(sysUser.getTenantId());
+        return succeed(sysMusicCompareRecordService.rankingList(queryInfo));
+    }
+
+    @ApiOperation("学员训练数据统计")
+    @GetMapping("studentTrainData")
+    public HttpResponseResult studentTrainData(SysMusicCompareRecordQueryInfo.TeacherCompareRecordQueryInfo queryInfo){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        queryInfo.setUserId(sysUser.getId());
+        return succeed(sysMusicCompareRecordService.studentTrainData(queryInfo));
+    }
+
+}

+ 24 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TaskController.java

@@ -0,0 +1,24 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.yonge.cooleshow.biz.dal.service.TenantPersonStatService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+@RestController
+@RequestMapping("${app-config.url.tenant:}/task")
+@ApiIgnore
+public class TaskController extends BaseController {
+
+    @Autowired
+    private TenantPersonStatService tenantPersonStatService;
+
+    //机构人员汇总
+    @GetMapping("/tenantPersonStat")
+    public void tenantPersonStat() {
+        tenantPersonStatService.tenantPersonStatTask();
+    }
+}

+ 155 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TeacherController.java

@@ -0,0 +1,155 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
+import com.yonge.cooleshow.biz.dal.dto.search.TeacherSearch;
+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.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.cooleshow.common.enums.UserStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.CollectionUtils;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("${app-config.url.tenant:}/teacher")
+@Api(value = "教师表", tags = "教师表")
+public class TeacherController extends BaseController {
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<TeacherVo> detail(@PathVariable("id") Long userId) {
+        TenantInfo tenantInfo = getTenantInfo();
+
+        TeacherVo detail = teacherService.findTeacherDetailInfo(userId);
+        if (detail == null) {
+            throw new BizException("数据不存在");
+        }
+        if (tenantInfo.getId().equals(detail.getTenantId())) {
+            throw new BizException("非法请求");
+        }
+        if (!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);
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入teacher")
+    public HttpResponseResult<PageInfo<TeacherVo>> page(@RequestBody TeacherSearch query) {
+        TenantInfo tenantInfo = getTenantInfo();
+        query.setTenantId(tenantInfo.getId());
+        query.setDelFlag(YesOrNoEnum.NO);
+        query.setOrderBy("u.username_ asc");
+
+        IPage<TeacherVo> pages = teacherService.selectPage(PageUtil.getPage(query), query);
+        List<TeacherVo> rows = pages.getRecords();
+
+        for (TeacherVo vo : rows) {
+            if (StringUtils.isNotEmpty(vo.getPhone())) {
+                vo.setPhone(vo.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"));
+            }
+            if (vo.getDelFlag() == YesOrNoEnum.YES) {
+                vo.setUserStatus(UserStatusEnum.CLOSED);
+            } else {
+                if (vo.getLockFlag() == UserLockFlag.LOCKED) {
+                    vo.setUserStatus(UserStatusEnum.LOCKED);
+                } else {
+                    vo.setUserStatus(UserStatusEnum.NORMAL);
+                }
+            }
+        }
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增或修改", notes = "传入teacher")
+    public HttpResponseResult<Boolean> submit(@Valid @RequestBody TeacherSubmitReq teacherSubmitReq) {
+        TenantInfo tenantInfo = getTenantInfo();
+        if (teacherSubmitReq.getUserId() != null) {
+            Teacher teacher = teacherService.lambdaQuery().eq(Teacher::getUserId, teacherSubmitReq.getUserId())
+                    .eq(Teacher::getTenantId, tenantInfo.getId()).last("limit 1").one();
+            if (teacher == null) {
+                throw new BizException("老师不存在");
+            }
+        } else {
+            // 新增 默认机构为操作人的机构
+            teacherSubmitReq.setTenantId(tenantInfo.getId());
+        }
+        return teacherService.submit(teacherSubmitReq);
+    }
+
+    @PostMapping("/setSettlement")
+    @ApiOperation(value = "设置结算方式")
+    public HttpResponseResult<Boolean> setSettlement(@Valid @RequestBody TeacherWrapper.TeacherSetSettlement setSettlement) {
+
+        List<Long> teacherIdList = setSettlement.getTeacherIdList();
+        if (teacherIdList.isEmpty()) {
+            throw new BizException("未选择老师");
+        }
+
+        TenantInfo tenantInfo = getTenantInfo();
+        teacherService.lambdaUpdate()
+                .set(Teacher::getSettlementFrom, setSettlement.getSettlementFrom())
+                .eq(Teacher::getTenantId, tenantInfo.getId())
+                .in(Teacher::getUserId, setSettlement.getTeacherIdList()).update();
+        return succeed();
+    }
+
+    private TenantInfo getTenantInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+        return tenantInfo;
+    }
+}

+ 240 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantActivationCodeController.java

@@ -0,0 +1,240 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantActivationCode;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.BizHttpStatus;
+import com.yonge.cooleshow.common.enums.EActivationCode;
+import com.yonge.cooleshow.tenant.vo.TenantActivationCodeVo;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.easyexcel.ErrMsg;
+import com.yonge.toolset.utils.easyexcel.ExcelDataReader;
+import com.yonge.toolset.utils.easyexcel.ExcelException;
+import com.yonge.toolset.utils.easyexcel.ExcelUtils;
+import com.yonge.toolset.utils.excel.POIUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.util.Date;
+import java.util.List;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/tenantActivationCode")
+@Api(tags = "机构激活码")
+public class TenantActivationCodeController extends BaseController {
+
+    @Autowired
+    private TenantActivationCodeService tenantActivationCodeService;
+
+    @Autowired
+    private TenantAlbumPurchaseService tenantAlbumPurchaseService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @ApiOperation(value = "详情", notes = "机构激活码-根据详情ID查询单条, 传入id")
+//    @GetMapping("/detail/{id}")
+    public R<TenantActivationCodeVo.TenantActivationCode> detail(@PathVariable("id") Long id) {
+
+        TenantActivationCode wrapper = tenantActivationCodeService.detail(id);
+
+        return R.from(TenantActivationCodeVo.TenantActivationCode.from(JSON.toJSONString(wrapper)));
+    }
+
+    @ApiOperation(value = "查询分页", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCodeQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantActivationCodeWrapper.TenantActivationCode>> page(
+            @RequestBody TenantActivationCodeWrapper.TenantActivationCodeQuery query) {
+        TenantInfo tenantInfo = getTenantInfo();
+        query.setTenantId(tenantInfo.getId());
+        // 查询数据
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> pages =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        PageInfo<TenantActivationCodeWrapper.TenantActivationCode> pageInfo = QueryInfo.pageInfo(pages,
+                pages.getRecords());
+
+        if (query.getTenantAlbumPurchaseId() != null) {
+            TenantActivationCodeWrapper.TenantActivationCode extra =
+                    new TenantActivationCodeWrapper.TenantActivationCode();
+            TenantAlbumPurchase purchase = tenantAlbumPurchaseService.getById(query.getTenantAlbumPurchaseId());
+            extra.setActiveQuantity(purchase.getActiveQuantity());
+            pageInfo.setExtra(extra);
+        }
+
+        return succeed(pageInfo);
+    }
+
+    @ApiOperation(value = "激活码发放", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCodeSend")
+    @PostMapping("/send")
+    public HttpResponseResult<Boolean> send(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCodeSend send) {
+        TenantInfo tenantInfo = getTenantInfo();
+        tenantActivationCodeService.sendActivationCode(tenantInfo.getId(), send.getTenantAlbumPurchaseId(),
+                send.getActivationCodeList(),
+                send.getStudentIdList());
+        return succeed();
+    }
+
+    @ApiOperation(value = "激活码发放取消", notes = "传入 激活码的ID")
+    @PostMapping("/sendCancel")
+    public HttpResponseResult<Boolean> sendCancel(@RequestParam("id") Long id) {
+        TenantInfo tenantInfo = getTenantInfo();
+        TenantActivationCode activationCode = tenantActivationCodeService.getById(id);
+        if (activationCode == null || !tenantInfo.getId().equals(activationCode.getTenantId())) {
+            throw new BizException("激活码不存在");
+        }
+        boolean update = tenantActivationCodeService.lambdaUpdate()
+                .set(TenantActivationCode::getSendStatus, EActivationCode.WAIT)
+                .eq(TenantActivationCode::getTenantId, id)
+                .eq(TenantActivationCode::getActivationStatus, false)
+                .eq(TenantActivationCode::getSendStatus, EActivationCode.SEND)
+                .update();
+        if (!update) {
+            throw new BizException("激活码已经激活");
+        }
+        return succeed();
+    }
+
+    @GetMapping("/exportActiveCode")
+    @ApiOperation(value = "导出模板")
+    public void exportActiveCode(HttpServletResponse response) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        Long tenantId = sysUser.getTenantId();
+
+        TenantActivationCodeWrapper.TenantActivationCodeQuery query =
+                new TenantActivationCodeWrapper.TenantActivationCodeQuery();
+        query.setTenantId(tenantId);
+        query.setActivationStatus(false);
+        query.setPage(1);
+        query.setRows(9999);
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> queryInfo =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        List<TenantActivationCodeWrapper.TenantActivationCode> rows = queryInfo.getRecords();
+        if (rows.isEmpty()) {
+            throw new BizException("没有可导出数据");
+        }
+
+        try (OutputStream outputStream = response.getOutputStream()) {
+            HSSFWorkbook workbook = POIUtil.exportExcel(new String[]{"激活码", "手机号"}, new String[]{
+                    "activationCode", "activationPhone"}, rows);
+            response.setContentType("application/octet-stream");
+            response.setHeader("Content-Disposition", "attac:wq" +
+                    "hment;filename=active_code-" + DateUtil.getDate(new Date()) + ".xls");
+            workbook.write(outputStream);
+            outputStream.flush();
+        } catch (Exception e) {
+            log.error("导出激活码异常", e);
+        }
+    }
+
+    @PostMapping("/importActiveCode")
+    @ApiOperation(value = "导入", notes = "传入file")
+    public HttpResponseResult<List<ErrMsg>> importActiveCode(
+            @RequestParam("file") MultipartFile file,
+            @RequestParam("tenantAlbumPurchaseId") Long tenantAlbumPurchaseId) {
+        if (null == file) {
+            return HttpResponseResult.failed("请上传文件");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByUserId(user.getId());
+        if (tenantStaff == null) {
+            return HttpResponseResult.failed("权限不足");
+        }
+
+        try {
+            ExcelDataReader<TenantActivationCodeWrapper.ImportTemplate> reader =
+                    ExcelUtils.getReader(TenantActivationCodeWrapper.ImportTemplate.class, file);
+            tenantActivationCodeService.importActiveCode(reader.getDataList(), user.getTenantId(), user.getId(),
+                    tenantAlbumPurchaseId);
+            return HttpResponseResult.succeed();
+        } catch (ExcelException e) {
+            return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(),
+                    BizHttpStatus.IMPORT.getMsg());
+        }
+    }
+
+    @ApiOperation(value = "新增", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCode")
+//    @PostMapping("/save")
+    public R<JSONObject> add(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCode tenantActivationCodeVo) {
+
+        // 新增数据
+        tenantActivationCodeService.save(JSON.parseObject(tenantActivationCodeVo.jsonString(),
+                TenantActivationCode.class));
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "修改", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCode")
+//    @PostMapping("/update")
+    public R<JSONObject> update(@Validated @RequestBody TenantActivationCodeVo.TenantActivationCode tenantActivationCodeVo) {
+
+        // 更新数据
+        tenantActivationCodeService.updateById(JSON.parseObject(tenantActivationCodeVo.jsonString(),
+                TenantActivationCode.class));
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "删除", notes = "机构激活码- 传入id")
+//    @PostMapping("/remove")
+    public R<Boolean> remove(@RequestParam Long id) {
+
+        return R.from(tenantActivationCodeService.removeById(id));
+    }
+
+    private TenantInfo getTenantInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+        return tenantInfo;
+    }
+}

+ 116 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumController.java

@@ -0,0 +1,116 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbum;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.tenant.vo.TenantAlbumVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/tenantAlbum")
+@Api(tags = "机构专辑")
+public class TenantAlbumController extends BaseController {
+
+    @Autowired
+    private TenantAlbumService tenantAlbumService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @ApiOperation(value = "详情", notes = "机构专辑-根据详情ID查询单条, 传入id")
+//    @GetMapping("/detail/{id}")
+    public HttpResponseResult<TenantAlbumVo.TenantAlbum> detail(@PathVariable("id") Long id) {
+        TenantAlbum wrapper = tenantAlbumService.detail(id);
+        return succeed(TenantAlbumVo.TenantAlbum.from(JSON.toJSONString(wrapper)));
+    }
+
+    @ApiOperation(value = "查询分页", notes = "机构专辑- 传入 TenantAlbumVo.TenantAlbumQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantAlbumVo.TenantAlbum>> page(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
+        TenantInfo tenantInfo = getTenantInfo();
+        query.setTenantId(tenantInfo.getId());
+        // 查询数据
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        // 数据类型转换
+        List<TenantAlbumVo.TenantAlbum> records = JSON.parseArray(JSON.toJSONString(pages.getRecords()),
+                TenantAlbumVo.TenantAlbum.class);
+        return succeed(QueryInfo.pageInfo(pages, records));
+    }
+
+    @ApiOperation(value = "采购专辑", notes = "机构专辑- 传入 TenantAlbumVo.TenantAlbumQuery")
+    @PostMapping("/buyAlbum")
+    public HttpResponseResult<Boolean> buyAlbum(@RequestBody TenantAlbumWrapper.TenantAlbumBuy buy) {
+        // todo 订单接入
+        return succeed();
+    }
+
+    @ApiOperation(value = "新增", notes = "机构专辑- 传入 TenantAlbumVo.TenantAlbum")
+//    @PostMapping("/add")
+    public HttpResponseResult<JSONObject> add(@Validated @RequestBody TenantAlbumVo.TenantAlbum tenantAlbumVo) {
+
+        // 新增数据
+        tenantAlbumService.save(JSON.parseObject(tenantAlbumVo.jsonString(), TenantAlbum.class));
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", notes = "机构专辑- 传入 TenantAlbumVo.TenantAlbum")
+//    @PostMapping("/update")
+    public HttpResponseResult<JSONObject> update(@Validated @RequestBody TenantAlbumVo.TenantAlbum tenantAlbumVo) {
+
+        // 更新数据
+        tenantAlbumService.updateById(JSON.parseObject(tenantAlbumVo.jsonString(), TenantAlbum.class));
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "机构专辑- 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbum/remove', {'BACKEND'})")
+//    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+        return HttpResponseResult.succeed(tenantAlbumService.removeById(id));
+    }
+
+    private TenantInfo getTenantInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+        return tenantInfo;
+    }
+
+}

+ 116 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantAlbumPurchaseController.java

@@ -0,0 +1,116 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantAlbumPurchase;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumPurchaseService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumPurchaseWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.tenant.vo.TenantAlbumPurchaseVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/tenantAlbumPurchase")
+@Api(tags = "机构专辑采购")
+public class TenantAlbumPurchaseController extends BaseController {
+
+    @Autowired
+    private TenantAlbumPurchaseService tenantAlbumPurchaseService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @ApiOperation(value = "详情", notes = "机构专辑采购-根据详情ID查询单条, 传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbumPurchase/detail', {'BACKEND'})")
+//    @GetMapping("/detail/{id}")
+    public HttpResponseResult<TenantAlbumPurchaseWrapper.TenantAlbumPurchase> detail(@PathVariable("id") Long id) {
+
+        TenantAlbumPurchase wrapper = tenantAlbumPurchaseService.detail(id);
+
+        return succeed(TenantAlbumPurchaseWrapper.TenantAlbumPurchase.from(JSON.toJSONString(wrapper)));
+    }
+
+    @ApiOperation(value = "查询分页", notes = "机构专辑采购- 传入 TenantAlbumPurchaseVo.TenantAlbumPurchaseQuery")
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbumPurchase/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantAlbumPurchaseWrapper.TenantAlbumPurchase>> page(
+            @RequestBody TenantAlbumPurchaseWrapper.TenantAlbumPurchaseQuery query) {
+        TenantInfo tenantInfo = getTenantInfo();
+        query.setTenantId(tenantInfo.getId());
+        // 查询数据
+        IPage<TenantAlbumPurchaseWrapper.TenantAlbumPurchase> pages =
+                tenantAlbumPurchaseService.selectPage(QueryInfo.getPage(query), query);
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "新增", notes = "机构专辑采购- 传入 TenantAlbumPurchaseVo.TenantAlbumPurchase")
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbumPurchase/save', {'BACKEND'})")
+//    @PostMapping("/save")
+    public HttpResponseResult<JSONObject> add(
+            @Validated @RequestBody TenantAlbumPurchaseVo.TenantAlbumPurchase tenantAlbumPurchaseVo) {
+
+        // 新增数据
+        tenantAlbumPurchaseService.save(JSON.parseObject(tenantAlbumPurchaseVo.jsonString(),
+                TenantAlbumPurchase.class));
+        return succeed();
+    }
+
+    @ApiOperation(value = "修改", notes = "机构专辑采购- 传入 TenantAlbumPurchaseVo.TenantAlbumPurchase")
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbumPurchase/update', {'BACKEND'})")
+//    @PostMapping("/update")
+    public HttpResponseResult<JSONObject> update(@Validated @RequestBody TenantAlbumPurchaseVo.TenantAlbumPurchase tenantAlbumPurchaseVo
+    ) {
+        // 更新数据
+        tenantAlbumPurchaseService.updateById(JSON.parseObject(tenantAlbumPurchaseVo.jsonString(),
+                TenantAlbumPurchase.class));
+        return succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "机构专辑采购- 传入id")
+//    @PreAuthorize("@auditsvc.hasPermissions('tenantAlbumPurchase/remove', {'BACKEND'})")
+//    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam Long id) {
+
+        return succeed(tenantAlbumPurchaseService.removeById(id));
+    }
+
+    private TenantInfo getTenantInfo() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        TenantInfo tenantInfo = tenantInfoService.lambdaQuery().eq(TenantInfo::getUserId, sysUser.getId())
+                .last("limit 1").one();
+        if (tenantInfo == null) {
+            throw new BizException("非法请求");
+        }
+        return tenantInfo;
+    }
+}

+ 173 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantInfoController.java

@@ -0,0 +1,173 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantInfoWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+import com.yonge.cooleshow.tenant.io.request.SysUserWrapper;
+import com.yonge.cooleshow.tenant.io.request.TenantInfoVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/24 9:57
+ * @Filename:TenantInfoController
+ */
+@RestController
+@RequestMapping("${app-config.url.tenant:}/tenantInfoUpdate")
+@Api(value = "机构信息修改", tags = "机构信息修改")
+public class TenantInfoController extends BaseController {
+
+    @Autowired
+    TenantInfoService tenantInfoService;
+
+    @Autowired
+    SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required =
+                    true, dataType = "String")})
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile, String type) throws Exception {
+        smsCodeService.sendValidCode(mobile, type, ClientEnum.SYSTEM);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required =
+                    true, dataType = "String")})
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone, String code, String type) {
+        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if (smsCodeService.verifyValidCode(phone, code, type)) {
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+
+    /**
+     * 机构修改数据
+     */
+    @PostMapping("/update")
+    @ApiOperation(value = "修改机构信息", notes = "传入TenantInfo")
+//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/update')")
+    public HttpResponseResult<Boolean> updateTenantInfo(@Valid @RequestBody TenantInfoVo.TenantInfo info) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        Long id = sysUser.getId();
+        TenantStaff staff = tenantStaffService.lambdaQuery().eq(TenantStaff::getUserId, id).list().get(0);
+        Long tenantId = staff.getTenantId();
+        return succeed(tenantInfoService.updateTenantInfo(JSON.parseObject(info.jsonString(), TenantInfo.class), tenantId));
+
+    }
+
+
+
+
+    /**
+     * 当前机构查询详细
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详细", notes = "查询详细")
+//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/detail')")
+    public HttpResponseResult<TenantInfoWrapper.TenantInfo> detail() {
+        TenantInfoWrapper.TenantInfo info = new TenantInfoWrapper.TenantInfo();
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        Long id = sysUser.getId();
+        TenantStaff staff = tenantStaffService.lambdaQuery().eq(TenantStaff::getUserId, id).list().get(0);
+        Long tenantId = staff.getTenantId();
+        if (!(tenantId == null)){
+            info = tenantInfoService.detailTenantInfo(id);
+        }
+        return succeed(info);
+    }
+
+
+
+    /**
+     * 当前用户查询详细
+     */
+    @PostMapping("/sysUserDetail")
+    @ApiOperation(value = "查询详细", notes = "查询详细")
+//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/sysUserDetail')")
+    public HttpResponseResult<SysUser> sysUserDetail() {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+
+
+        return HttpResponseResult.succeed(sysUser);
+    }
+
+    /**
+     * 当前用户修改信息
+     */
+    @PostMapping("/sysUserUpdate")
+    @ApiOperation(value = "用户修改", notes = "用户修改")
+//    @PreAuthorize("@pcs.hasPermissions('tenantInfoUpdate/sysUserUpdate')")
+    public HttpResponseResult<Boolean> sysUserUpdate(SysUserWrapper.SysUser sysUser) {
+        com.yonge.cooleshow.biz.dal.entity.SysUser sysUser1 = JSON.parseObject(sysUser.jsonString(), com.yonge.cooleshow.biz.dal.entity.SysUser.class);
+        SysUser user = sysUserFeignService.queryUserInfo();
+        tenantInfoService.updateSysUser(sysUser1,user.getId());
+
+        //判断更改的手机所属的机构信息
+        String phone = sysUser.getPhone();
+
+        //设置默认头像
+        if (sysUser.getAvatar().isEmpty()){
+            sysUser.setAvatar(sysConfigService.findConfigValue(SysConfigConstant.DEFAULT_HEARD));
+        }
+
+        TenantInfo info = tenantInfoService.lambdaQuery().eq(TenantInfo::getPhone, phone).list().get(0);
+        if (!(info == null)){
+            //更新tennatInfo
+            tenantInfoService.lambdaUpdate().set(TenantInfo::getPhone,phone)
+                                            .eq(TenantInfo::getUserId,user.getId());
+
+            //更新员工表
+            tenantStaffService.lambdaUpdate().set(TenantStaff::getNickname,sysUser.getUsername())
+                                             .set(TenantStaff::getAvatar,sysUser.getAvatar())
+                                             .eq(TenantStaff::getUserId,user.getId());
+        }
+
+
+
+        return HttpResponseResult.succeed(true);
+    }
+
+}

+ 84 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/TenantUnbindRecordController.java

@@ -0,0 +1,84 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.service.TenantUnbindRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantUnbindRecordWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.UserLockFlag;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/tenantUnbindRecord")
+@Api(tags = "机构解绑申请记录")
+public class TenantUnbindRecordController extends BaseController {
+
+    @Autowired
+    private TenantUnbindRecordService tenantUnbindRecordService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+
+    @ApiOperation(value = "查询分页", notes = "机构解绑申请记录- 传入 TenantUnbindRecordVo.TenantUnbindRecordQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantUnbindRecordWrapper.TenantUnbindRecord>>
+    page(@RequestBody TenantUnbindRecordWrapper.TenantUnbindRecordQuery query) {
+        // 查询数据
+        IPage<TenantUnbindRecordWrapper.TenantUnbindRecord> pages =
+                tenantUnbindRecordService.selectPage(QueryInfo.getPage(query), query);
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "审核")
+    @PostMapping("/audit")
+    public HttpResponseResult<Boolean> audit(@RequestBody TenantUnbindRecordWrapper.Audio audio) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        Long id = sysUserFeignService.queryUserInfo().getId();
+        TenantStaff employeeVo = tenantStaffService.lambdaQuery().eq(TenantStaff::getUserId, id)
+                .last("limit 1").one();
+        if (employeeVo == null || UserLockFlag.LOCKED.equals(employeeVo.getStatus())) {
+            throw new BizException("权限不足");
+        }
+        tenantUnbindRecordService.tenantUserUnbindAudit(audio, sysUser.getId(), false);
+        return succeed();
+    }
+
+    @PostMapping("/unbindTenant")
+    @ApiOperation(value = "机构解绑")
+    public HttpResponseResult<Boolean> unbindTenant(@Validated @RequestBody TenantUnbindRecordWrapper.Unbind unbind) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            throw new BizException("请登录");
+        }
+        tenantUnbindRecordService.unbindTenant(sysUser.getTenantId(), sysUser.getId(), unbind);
+        return succeed();
+
+    }
+
+
+}

+ 208 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/UserOrderController.java

@@ -0,0 +1,208 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.OrderPayReq;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.entity.UserOrder;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.cooleshow.common.enums.EPaymentVersion;
+import com.yonge.cooleshow.tenant.vo.UserPaymentOrderVo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.payment.util.DistributedLock;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.redisson.api.RedissonClient;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.succeed;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/userOrder")
+@Api(tags = "用户支付订单")
+public class UserOrderController {
+
+
+    @Autowired
+    private UserOrderService userOrderService;
+    @Autowired
+    private RedissonClient redissonClient;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @ApiOperation(value = "用户下单", notes = "用户下单")
+    @PostMapping("/executeOrder/v2")
+    public R<UserPaymentOrderWrapper.PaymentConfig> executeOrder(@Validated @RequestBody UserPaymentOrderVo.OrderReq orderReq) {
+
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
+        orderReq.setUserId(sysUser.getId());
+        orderReq.setPaymentClient(ClientEnum.TENANT.name());
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.UserPaymentOrder order = JSON.parseObject(orderReq.jsonString(), UserPaymentOrderWrapper.UserPaymentOrder.class);
+
+        TenantStaff tenantStaff = tenantStaffService.getByUserId(sysUser.getId());
+        if (Objects.isNull(tenantStaff)) {
+            throw BizException.from("用户信息不存在");
+        }
+
+        order.setTenantId(tenantStaff.getTenantId());
+        // 新增数据
+        UserPaymentOrderWrapper.PaymentConfig paymentConfig = userPaymentCoreService.executeOrderCreate(order);
+        if (Objects.isNull(paymentConfig)) {
+            throw BizException.from("下单失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment/v2")
+    public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config, HttpServletRequest request) {
+        // 设置下单用户信息
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            throw BizException.from("用户信息不存在");
+        }
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
+
+        reqConfig.setIp(ServletUtil.getClientIP(request));
+        // 创建用户支付数据
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(sysUser.getId().toString()).clientType(ClientEnum.TENANT.getCode()).build(), reqConfig);
+        if (Objects.isNull(paymentConfig)) {
+            throw BizException.from("付款失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+
+
+    @ApiOperation(value = "取消订单")
+    @PostMapping("/orderCancel")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderNo", value = "订单号", paramType = "query", dataType = "String", required = true),
+            @ApiImplicitParam(name = "reason", value = "取消说明", paramType = "query", dataType = "String")
+    })
+    public HttpResponseResult<Boolean> orderCancel(@ApiIgnore @RequestBody OrderPayReq payReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(payReq.getOrderNo())) {
+            return failed("订单号不能为空");
+        }
+        payReq.setUserId(user.getId());
+
+        UserOrder order = userOrderService.getByOrderNo(payReq.getOrderNo());
+        if (null == order) {
+            return failed("订单不存在");
+        }
+        if(order.getPaymentVersion().equals(EPaymentVersion.V2)){
+
+
+            // 用户取消支付
+            userPaymentCoreService.cancelPayment(JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.STUDENT.getCode()).build(), payReq.getOrderNo());
+        } else {
+
+            try {
+                HttpResponseResult<Boolean> res = DistributedLock.of(redissonClient)
+                        .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(payReq.getOrderNo())
+                                , userOrderService::orderCancel, payReq, 10L);
+                if (null != res) {
+                    return res;
+                } else {
+                    return HttpResponseResult.failed("取消订单失败");
+                }
+            } catch (com.yonge.toolset.base.exception.BizException e) {
+                return HttpResponseResult.failed(e.getMessage());
+            } catch (Exception e) {
+                e.printStackTrace();
+                return HttpResponseResult.failed("取消订单失败");
+            }
+        }
+        return succeed();
+    }
+
+    @ApiOperation(value = "取消订单")
+    @PostMapping("/orderCancel/v2")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "orderNo", value = "订单号", paramType = "query", dataType = "String", required = true),
+            @ApiImplicitParam(name = "reason", value = "取消说明", paramType = "query", dataType = "String")
+    })
+    public HttpResponseResult<Boolean> orderCancelV2(@ApiIgnore @RequestBody OrderPayReq payReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(payReq.getOrderNo())) {
+            return failed("订单号不能为空");
+        }
+        payReq.setUserId(user.getId());
+
+        // 用户取消支付
+        userPaymentCoreService.cancelPayment(JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.TENANT.getCode()).build(), payReq.getOrderNo());
+
+        return HttpResponseResult.status(true);
+    }
+
+
+    @ApiOperation(value = "检测订单应该使用哪种支付方式")
+    @PostMapping("/orderPayType")
+    public HttpResponseResult<UserPaymentOrderWrapper.OrderPayTypeResp> orderPayType( @RequestBody UserPaymentOrderWrapper.OrderPayTypeReq payTypeReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        payTypeReq.setBuyId(user.getId());
+        payTypeReq.setClientType(ClientEnum.TENANT);
+
+        // 用户取消支付
+
+
+        return succeed(userPaymentCoreService.orderPayType(payTypeReq));
+    }
+
+
+
+}

+ 53 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/WechatMusicCompareRecordController.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.tenant.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Api(tags = "机构端训练记录")
+@RequestMapping("${app-config.url.tenant:}/wechatMusicCompareRecord")
+@RestController
+public class WechatMusicCompareRecordController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+
+    @ApiOperation("学员评测记录")
+    @PostMapping("queryStudentTrain")
+    public HttpResponseResult<PageInfo<SysMusicCompareRecordQueryInfo.StudentMusicCompareRecord>>
+    queryStudentTrain(SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(sysMusicCompareRecordService.queryStudentTrain(query));
+    }
+
+
+    @ApiOperation("学员训练统计以及基本信息查询")
+    @PostMapping("studentTrainStat")
+    public HttpResponseResult<SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordStat>
+    studentMusicCompareRecordStat(SysMusicCompareRecordQueryInfo.StudentMusicCompareRecordQuery query){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("获取用户信息失败");
+        }
+        query.setTenantId(sysUser.getTenantId());
+        return succeed(sysMusicCompareRecordService.studentMusicCompareRecordStat(query));
+    }
+
+}

+ 70 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenClient.java

@@ -0,0 +1,70 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.microsvc.toolkit.middleware.oss.wrapper.OssWrapper;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.biz.dal.vo.CheckVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.thirdparty.entity.UploadSign;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open")
+@Api(value = "开放权限接口", tags = "开放权限接口")
+public class OpenClient extends BaseController {
+
+    @Autowired
+    private UploadFileService uploadFileService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "bucketName", dataType = "String", value = "为空时默认使用daya"),
+            @ApiImplicitParam(name = "fileName", dataType = "String", value = "要上传的文件名称,不包含路径信息"),
+            @ApiImplicitParam(name = "postData", dataType = "Map", value = "1.如果使用js sdk上传的时候设置了ACL请设置,例\"acl\":\"public-read\"值要与SDK中一致,没有则删除该项</br>" +
+                    "2.提供js sdk中的key值,例\"key\":\"20150115/中文/${filename}\""),
+            @ApiImplicitParam(name = "unknowValueField", dataType = "List", value = "对于用户无法确定表单值的放在unknownValueField中(比如有的上传控件会添加一些表单项,但表单项的值可能是随机的)"),
+            @ApiImplicitParam(name = "pluginName", dataType = "String", value = "插件名称,默认ks3,可选值:ks3,aliyun,tencent"),
+    })
+    @ApiOperation(value = "获取上传文件签名", notes = "{\n" +
+            "    \"bucketName\":\"\",\n" +
+            "    \"filename\":\"test.png\",\n" +
+            "    \"postData\":{\n" +
+            "        \"acl\":\"public-read\",\n" +
+            "        \"key\":\"20150115/中文/${filename}\"\n" +
+            "    },\n" +
+            "    \"unknowValueField\":[\"test\"]\n" +
+            "}")
+    @PostMapping("/getUploadSign")
+    public HttpResponseResult<OssWrapper.ResponseSign> getUploadSign(@RequestParam(defaultValue = "ks3") String pluginName,
+                                                                     @RequestBody UploadSign uploadSign) {
+        // 设置默认文件存储服务方
+        uploadSign.setPluginName(pluginName);
+        return succeed(uploadFileService.getUploadSign(uploadSign));
+    }
+
+    @PostMapping("/appVersion")
+    @ApiOperation(value = "查询app是否为审核版本")
+    public HttpResponseResult<CheckVo> appVersion(@RequestBody Map<String,String> obj) {
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(obj.get("platform"), obj.get("version"));
+        CheckVo checkVo = new CheckVo();
+        checkVo.setCheck(appAuditVersion);
+        return succeed(checkVo);
+    }
+}

+ 150 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenStudentController.java

@@ -0,0 +1,150 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.google.common.collect.ImmutableList;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.ImGroupMember;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.ImGroupMemberService;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.biz.dal.wrapper.StudentWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.tenant.vo.StudentVo;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open/student")
+@Api(value = "学生表", tags = "学生表")
+public class OpenStudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
+    @Autowired
+    private ImUserFriendService imUserFriendService;
+
+    @Autowired
+    private ImGroupService imGroupService;
+
+    @Autowired
+    private ImGroupMemberService imGroupMemberService;
+
+    @PostMapping("/save")
+    @ApiOperation(value = "新增/修改", notes = "传入Student,换绑时按照返回错误码5004判断,是否需要换绑,updateTenant=true表示换绑")
+    public HttpResponseResult<Boolean> save(@Validated @RequestBody StudentVo.Student student) {
+        String code = student.getCode();
+        if (StringUtils.isEmpty(code)) {
+            throw new BizException("验证码不能为空");
+        }
+        if (!smsCodeService.verifyValidCode(student.getPhone(), code,
+                MessageTypeEnum.SMS_VERIFY_CODE_REGISTER.getCode())) {
+            throw new BizException("验证码错误");
+        }
+        Long tenantId = student.getTenantId();
+        if (tenantId == null) {
+            throw new BizException("未指定机构");
+        }
+        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
+        if (tenantInfo == null) {
+            throw new BizException("机构不存在");
+        }
+        Long studentId = student.getId();
+
+        if (studentId == null) {
+            SysUser sysUser = sysUserFeignService.queryUserByMobile(student.getPhone());
+            if (sysUser != null) {
+                studentId = sysUser.getId();
+            }
+        }
+
+        if (studentId != null) {
+            Student one = studentService.lambdaQuery()
+                    .eq(Student::getUserId, studentId)
+                    .eq(Student::getHideFlag, 0)
+                    .last("limit 1").one();
+            if (one != null) {
+                if (one.getTenantId().equals(-1L)) {
+                    throw new BizException("该手机号已经注册为平台学生");
+                }
+                if (one.getTenantId().equals(tenantId)) {
+                    throw new BizException("已经注册当前机构,请勿重复注册");
+                }
+                // 转到其他机构
+                if ((student.getUpdateTenant() == null ||
+                        !student.getUpdateTenant())) {
+                    throw new BizException(5004, "该手机号已经注册为其他平台学生");
+                }
+                // 退群
+                List<ImGroupMember> groupMembers = imGroupMemberService.lambdaQuery()
+                        .eq(ImGroupMember::getRoleType, ImGroupMemberRoleType.STUDENT)
+                        .eq(ImGroupMember::getIsAdmin, false)
+                        .eq(ImGroupMember::getUserId, one.getUserId())
+                        .list();
+                List<String> groupIdList = groupMembers.stream().map(ImGroupMember::getGroupId)
+                        .distinct().collect(Collectors.toList());
+                groupIdList.forEach(groupId -> {
+                    try {
+                        imGroupService.quit(groupId, one.getUserId(), ClientEnum.STUDENT);
+                    } catch (Exception e) {
+                        log.error("学生注册,切换机构退群失败:{}", e.getMessage());
+                    }
+                });
+            }
+            student.setId(studentId);
+        }
+
+
+        StudentWrapper.Student studentInfo = JSON.parseObject(JSON.toJSONString(student), StudentWrapper.Student.class);
+        studentInfo.setTenantId(tenantInfo.getId());
+        studentService.save(studentInfo);
+
+        // 加好友
+        if (student.getId() == null) {
+            SysUser sysUser = sysUserFeignService.queryUserByMobile(student.getPhone());
+            // 自动与机构老师成为好友
+            List<Teacher> teacherList = teacherService.lambdaQuery()
+                    .eq(Teacher::getTenantId, tenantId).list();
+            teacherList.forEach(next -> imUserFriendService.saveUserFriend(next.getUserId(),
+                    new HashSet<>(ImmutableList.of(sysUser.getId()))));
+        }
+        return succeed();
+    }
+}

+ 39 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenSubjectController.java

@@ -0,0 +1,39 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.queryInfo.SubjectQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RequestMapping("${app-config.url.tenant:}/open/subject")
+@Api(tags = "声部服务")
+@RestController
+public class OpenSubjectController extends BaseController {
+
+	@Autowired
+	private SubjectService subjectService;
+
+	@ApiOperation(value = "根据声部编号查询声部")
+	@GetMapping("/get/{id}")
+	public Object get(@ApiParam(value = "声部编号", required = true) @PathVariable("id") Long id) {
+		return succeed(subjectService.get(id));
+	}
+
+	@ApiOperation(value = "分页查询声部树状列表")
+	@PostMapping("/queryPageTree")
+	public HttpResponseResult<PageInfo<Subject>> queryPageTree(@RequestBody SubjectQueryInfo queryInfo) {
+		return succeed(subjectService.queryPageTree(queryInfo));
+	}
+}

+ 128 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenSysAreaController.java

@@ -0,0 +1,128 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.google.common.collect.Lists;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.yonge.cooleshow.biz.dal.entity.SysArea;
+import com.yonge.cooleshow.biz.dal.service.SysAreaService;
+import com.yonge.cooleshow.biz.dal.wrapper.SysAreaWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.tenant.io.request.SysAreaVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open/sysArea")
+@Api(tags = "区域表")
+public class OpenSysAreaController {
+
+    @Autowired
+    private SysAreaService sysAreaService;
+
+    /**
+     * 查询单条
+     * @param id 详情ID
+     * @return R<SysAreaVo.SysArea>
+     */
+    @ApiOperation(value = "详情", notes = "传入id")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "id", value = "id", dataType = "long")
+    })
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<SysAreaWrapper.SysArea> detail(@PathVariable("id") Long id) {
+
+        return HttpResponseResult.succeed(sysAreaService.detail(id));
+    }
+
+    /**
+     * 根据code查询
+     * @param code 详情ID
+     * @return R<SysAreaVo.SysArea>
+     */
+    @ApiOperation(value = "根据code查询", notes = "传入code")
+    @GetMapping("/queryByCode/{code}")
+    public HttpResponseResult<SysArea> queryByCode(@PathVariable("code") Integer code) {
+
+        List<Integer> codeList = new ArrayList<Integer>();
+        codeList.add(code);
+        List<SysArea> list = sysAreaService.queryByCodes(codeList);
+
+        if(list == null || list.size() == 0){
+            throw BizException.from("根据code查询区域表失败");
+        }
+
+        return HttpResponseResult.succeed(list.get(0));
+    }
+
+    /**
+     * 查询分页
+     * @param query SysAreaVo.SysAreaQuery
+     * @return R<PageInfo<SysAreaVo.SysAreaList>>
+     */
+    @ApiOperation(value = "查询分页", notes = "传入sysAreaSearch")
+//    @PreAuthorize("@auditsvc.hasPermissions('sysArea/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<SysAreaWrapper.SysArea>> page(@RequestBody SysAreaWrapper.SysAreaQuery query) {
+
+        IPage<SysAreaWrapper.SysArea> pages = sysAreaService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+    /**
+     * 查询全部区域
+     * @return R<List<SysAreaVo.Province>>
+     */
+    @ApiOperation(value = "查询全部区域", notes = "查询全部区域")
+    @GetMapping("/queryAllProvince")
+    public HttpResponseResult<List<SysAreaVo.Province>> queryAllProvince() {
+
+        List<SysAreaVo.Province> provinces = Lists.newArrayList();
+
+        // 全部城市信息
+        Map<Integer, List<SysArea>> areaMap = sysAreaService.lambdaQuery().list().stream()
+                .filter(x -> x.getDelFlag().equals("0"))
+                .collect(Collectors.groupingBy(SysArea::getParentOrganId));
+
+        SysAreaVo.Province provinceVo;
+        SysAreaVo.City cityVo;
+        for (SysArea province : areaMap.get(0)) {
+
+            provinceVo = JSON.parseObject(JSON.toJSONString(province), SysAreaVo.Province.class)
+                    .cities(Lists.newArrayList());
+            provinces.add(provinceVo);
+
+            // 城市信息
+            for (SysArea city : areaMap.get(province.getId())) {
+
+                cityVo = JSON.parseObject(JSON.toJSONString(city), SysAreaVo.City.class);
+                provinceVo.getAreas().add(cityVo);
+
+                if (areaMap.containsKey(city.getId())) {
+                    cityVo.setAreas(JSON.parseArray(JSON.toJSONString(areaMap.get(city.getId())), SysAreaVo.District.class));
+                }
+            }
+        }
+
+        return HttpResponseResult.succeed(provinces);
+    }
+}

+ 52 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTeacherController.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherSubmitReq;
+import com.yonge.cooleshow.biz.dal.entity.TenantInfo;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TenantInfoService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * @author 袁亮
+ * @apiNote 二维码方式注册老师账号
+ */
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open/teacher")
+@Api(value = "教师表", tags = "教师表")
+public class OpenTeacherController extends BaseController {
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 新增或修改
+     */
+    @PostMapping("/submit")
+    @ApiOperation(value = "新增", notes = "传入teacher")
+    public HttpResponseResult<Boolean> submit(@Valid @RequestBody TeacherSubmitReq teacherSubmitReq) {
+        Long tenantId = teacherSubmitReq.getTenantId();
+        if (tenantId == null) {
+            throw new BizException("未选择机构");
+        }
+        TenantInfo tenantInfo = tenantInfoService.getById(tenantId);
+        if (tenantInfo == null || Boolean.FALSE.equals(tenantInfo.getEnableFlag())) {
+            throw new BizException("机构不可用");
+        }
+        teacherSubmitReq.setUserId(null);
+        return teacherService.submit(teacherSubmitReq);
+    }
+}

+ 85 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/OpenTenantController.java

@@ -0,0 +1,85 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import com.yonge.cooleshow.biz.dal.entity.TenantApplyRecord;
+import com.yonge.cooleshow.biz.dal.entity.TenantStaff;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.TenantApplyRecordService;
+import com.yonge.cooleshow.biz.dal.service.TenantStaffService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantApplyRecordWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@Validated
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open/tenant")
+@Api(tags = "机构")
+public class OpenTenantController {
+
+
+    @Autowired
+    private TenantApplyRecordService tenantApplyRecordService;
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
+
+    @PostMapping("/apply")
+    @ApiOperation(value = "申请")
+    public HttpResponseResult<Boolean> save(
+            @Validated @RequestBody TenantApplyRecordWrapper.TenantApply tenantApply) {
+
+        tenantApplyRecordService.apply(tenantApply);
+
+        return HttpResponseResult.status(true);
+    }
+
+
+    @GetMapping("/bindWechat")
+    @ApiOperation(value = "绑定微信")
+    public HttpResponseResult<Boolean> bindWechat(@RequestParam("phone") String phone,
+                                                  @RequestParam("openId") String openId,
+                                                  @RequestParam("code") String code) {
+        if (StringUtils.isEmpty(openId)) {
+            throw new BizException("openId不能为空");
+        }
+        if (StringUtils.isEmpty(phone)) {
+            throw new BizException("手机号不能为空");
+        }
+        // 校验验证码
+        boolean validCode = smsCodeService.verifyValidCode(phone, code, "LOGIN");
+        if (!validCode) {
+            throw new BizException("验证码错误");
+        }
+        TenantStaff tenantStaff = tenantStaffService.getByPhone(phone);
+        if (tenantStaff == null) {
+            TenantApplyRecord one = tenantApplyRecordService.lambdaQuery()
+                    .eq(TenantApplyRecord::getPhone, phone)
+                    .orderByDesc(TenantApplyRecord::getCreateTime)
+                    .last("limit 1").one();
+            if (one == null || AuthStatusEnum.UNPASS.equals(one.getStatus())) {
+                throw new BizException(5002, "请先申请机构入驻");
+            }
+            if (AuthStatusEnum.DOING.equals(one.getStatus())) {
+                throw new BizException(5003, "请等待审核完成");
+            }
+        }
+        tenantStaff.setWxOpenid(openId);
+        tenantStaffService.updateById(tenantStaff);
+        return HttpResponseResult.succeed();
+    }
+}

+ 52 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/controller/open/UserPaymentClient.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.tenant.controller.open;
+
+import cn.hutool.extra.servlet.ServletUtil;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import com.yonge.cooleshow.tenant.vo.UserPaymentOrderVo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+@Slf4j
+@RestController
+@RequestMapping("${app-config.url.tenant:}/open/userOrder")
+@Api(tags = "开放权限接口-支付回调")
+public class UserPaymentClient {
+
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
+    @ApiOperation(value = "用户付款", notes = "用户付款")
+    @PostMapping("/executePayment/v2")
+    public R<UserPaymentOrderWrapper.PaymentReq> executePayment(@Validated @RequestBody UserPaymentOrderVo.PaymentReqConfig config, HttpServletRequest request) {
+        // 设置下单用户信息
+
+
+        // 用户下单请求
+        UserPaymentOrderWrapper.PaymentOrderReqConfig reqConfig = UserPaymentOrderWrapper.PaymentOrderReqConfig.from(config.jsonString());
+
+        reqConfig.setIp(ServletUtil.getClientIP(request));
+        // 创建用户支付数据
+        UserPaymentOrderWrapper.PaymentReq paymentConfig = userPaymentCoreService.executePayment(JwtUserInfo.builder()
+                .userId(config.getUserId()).clientType(ClientEnum.TENANT.getCode()).build(), reqConfig);
+        if (Objects.isNull(paymentConfig)) {
+            throw BizException.from("付款失败");
+        }
+
+        return R.from(paymentConfig);
+    }
+}

+ 168 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/SysAreaVo.java

@@ -0,0 +1,168 @@
+package com.yonge.cooleshow.tenant.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 区域表
+ * 2022-11-23 18:28:58
+ */
+@ApiModel(value = "SysAreaVo对象", description = "区域表查询视图对象")
+public class SysAreaVo {
+
+    @Data
+    @ApiModel(" SysAreaList-区域表")
+    public static class SysAreaQuery implements QueryInfo {
+
+    	@ApiModelProperty("父节点")
+    	private Integer parentId;
+
+        @ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+    }
+
+    @Data
+    @ApiModel(" SysArea-区域表")
+    public static class SysArea {
+
+
+		@ApiModelProperty("")
+        private Integer id;
+
+
+		@ApiModelProperty("名称")
+        private String name;
+
+
+		@ApiModelProperty("编码")
+        private Integer code;
+
+
+		@ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+		@ApiModelProperty("修改时间")
+        private Date updateTime;
+
+
+		@ApiModelProperty("是否删除  -1:已删除  0:正常")
+        private String delFlag;
+
+
+		@ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+
+    @Data
+    @ApiModel(" SysAreaList-区域表")
+    public static class SysAreaList {
+
+
+		@ApiModelProperty("")
+        private Integer id;
+
+
+		@ApiModelProperty("名称")
+        private String name;
+
+
+		@ApiModelProperty("编码")
+        private Integer code;
+
+
+		@ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+		@ApiModelProperty("修改时间")
+        private Date updateTime;
+
+
+		@ApiModelProperty("是否删除  -1:已删除  0:正常")
+        private String delFlag;
+
+
+		@ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("区域数")
+        private Integer number;
+    }
+
+    @Data
+    @ApiModel("省份")
+    public static class Province implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+
+        @ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("城市")
+        private List<City> areas;
+
+
+        public Province cities(List<City> cities) {
+            this.areas = cities;
+            return this;
+        }
+    }
+
+    @Data
+    @ApiModel("城市")
+    public static class City implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+
+        @ApiModelProperty("父节点编号")
+        private Integer parentOrganId;
+
+        @ApiModelProperty("地区/街道")
+        private List<District> areas;
+
+    }
+
+    @Data
+    @ApiModel("地区/街道")
+    public static class District implements Serializable {
+
+        @ApiModelProperty("主键Id")
+        private Integer id;
+
+        @ApiModelProperty("名称")
+        private String name;
+
+        @ApiModelProperty("编码")
+        private Integer code;
+    }
+}

+ 39 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/SysUserWrapper.java

@@ -0,0 +1,39 @@
+package com.yonge.cooleshow.tenant.io.request;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 用户信息
+ * 2023-08-21 15:55:00
+ */
+@ApiModel(value = "用户对象", description = "用户对象")
+public class SysUserWrapper {
+
+    @Data
+    @ApiModel("sysUer")
+    public static class SysUser {
+
+        @ApiModelProperty(value = "用户名")
+        private String username;
+
+        @ApiModelProperty(value = "手机号")
+        private String phone;
+
+        /** 头像 */
+        @ApiModelProperty(value = "头像")
+        private String avatar;
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static SysUser from(String json) {
+            return JSON.parseObject(json, SysUser.class);
+        }
+    }
+
+}

+ 55 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/io/request/TenantInfoVo.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.tenant.io.request;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * 机构表
+ * 2023-08-01 11:19:12
+ */
+@ApiModel(value = "TenantInfoVo对象", description = "机构表查询视图对象")
+public class TenantInfoVo {
+
+    @Data
+    @ApiModel(" TenantInfo-机构表")
+    public static class TenantInfo {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("名称")
+        @NotNull
+        private String name;
+
+        @ApiModelProperty("logo")
+        private String logo;
+
+        @ApiModelProperty("简介")
+        private String briefIntroduction;
+
+        @ApiModelProperty("省份编码")
+        @NotNull
+        private Integer provinceCode;
+
+        @ApiModelProperty("城市编码")
+        @NotNull
+        private Integer cityCode;
+
+        @ApiModelProperty("地区/街道")
+        @NotNull
+        private Integer regionCode;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantInfo from(String json) {
+            return JSON.parseObject(json, TenantInfo.class);
+        }
+    }
+
+}

+ 52 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/StudentVo.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Pattern;
+import java.time.LocalDate;
+
+@ApiModel("学生入参模型")
+@Data
+public class StudentVo {
+
+    @Data
+    @ApiModel("添加/修改学生")
+    public static class Student {
+
+        @ApiModelProperty("id")
+        private Long id;
+
+        @ApiModelProperty("所属机构,开放接口必填")
+        private Long tenantId;
+
+        @ApiModelProperty("姓名")
+        @NotNull
+        private String name;
+
+        @ApiModelProperty("性别。0:女 1:男")
+        @NotNull
+        private Integer gender;
+
+        @ApiModelProperty("生日")
+        private LocalDate birthdate;
+
+        @ApiModelProperty("手机号码")
+        @Pattern(regexp = "^1\\d{10}$", message = "请输入正确的手机号码")
+        private String phone;
+
+        @ApiModelProperty("头像")
+        private String avatar;
+
+        @ApiModelProperty("声部,多个用逗号隔开")
+        private String subjectId;
+
+        @ApiModelProperty("是否换绑机构,开放接口使用参数")
+        private Boolean updateTenant;
+
+        @ApiModelProperty("短信验证码")
+        private String code;
+    }
+}

+ 99 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantActivationCodeVo.java

@@ -0,0 +1,99 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 机构激活码
+ * 2023-07-25 11:45:04
+ */
+@ApiModel(value = "TenantActivationCodeVo对象", description = "机构激活码查询视图对象")
+public class TenantActivationCodeVo {
+
+    @Data
+    @ApiModel(" TenantActivationCodeSend-机构激活码发放")
+    public static class TenantActivationCodeSend {
+
+        @ApiModelProperty("专辑购买记录的ID")
+        @NotNull(message = "专辑购买记录的ID不能为空")
+        private Long tenantAlbumPurchaseId;
+
+        @ApiModelProperty("激活码列表,批量发送时为空")
+        private List<String> activationCodeList = new ArrayList<>();
+
+        @ApiModelProperty("学生ID列表")
+        @Size(min = 1, message = "未选择学生")
+        private List<Long> studentIdList = new ArrayList<>();
+    }
+
+    @Data
+    @ApiModel(" TenantActivationCode-机构激活码")
+    public static class TenantActivationCode {
+
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+
+        @ApiModelProperty("机构专辑ID")
+        private Long tenantAlbumId;
+
+
+        @ApiModelProperty("机构专辑采购ID")
+        private Long tenantAlbumPurchaseId;
+
+
+        @ApiModelProperty("激活码")
+        private String activationCode;
+
+
+        @ApiModelProperty("发送状态(WAIT,SEND)")
+        private String sendStatus;
+
+
+        @ApiModelProperty("激活状态")
+        private Boolean activationStatus;
+
+
+        @ApiModelProperty("激活手机号")
+        private String activationPhone;
+
+
+        @ApiModelProperty("激活时间")
+        private Date activationTime;
+
+
+        @ApiModelProperty("激活用户ID")
+        private Long activationUserId;
+
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantActivationCode from(String json) {
+            return JSON.parseObject(json, TenantActivationCode.class);
+        }
+    }
+
+}

+ 64 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantAlbumPurchaseVo.java

@@ -0,0 +1,64 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 机构专辑采购
+ * 2023-07-25 11:05:33
+ */
+@ApiModel(value = "TenantAlbumPurchaseVo对象", description = "机构专辑采购查询视图对象")
+public class TenantAlbumPurchaseVo {
+
+    @Data
+    @ApiModel(" TenantAlbumPurchase-机构专辑采购")
+    public static class TenantAlbumPurchase {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("机构ID")
+        private Long tenantId;
+
+        @ApiModelProperty("机构专辑ID")
+        private Long tenantAlbumId;
+
+        @ApiModelProperty("采购时间")
+        private Date purchaseTime;
+
+        @ApiModelProperty("购买数量")
+        private Integer purchaseQuantity;
+
+        @ApiModelProperty("采购周期")
+        private Integer purchaseCycle;
+
+        @ApiModelProperty("激活数量")
+        private Integer activeQuantity;
+
+        @ApiModelProperty("采购价格")
+        private BigDecimal purchasePrice;
+
+        @ApiModelProperty("采购状态")
+        private String purchaseStatus;
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantAlbumPurchase from(String json) {
+            return JSON.parseObject(json, TenantAlbumPurchase.class);
+        }
+    }
+
+}

+ 83 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/TenantAlbumVo.java

@@ -0,0 +1,83 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 机构专辑
+ * 2023-07-25 10:27:37
+ */
+@ApiModel(value = "TenantAlbumVo对象", description = "机构专辑查询视图对象")
+public class TenantAlbumVo {
+
+    @Data
+    @ApiModel(" TenantAlbum-机构专辑")
+    public static class TenantAlbum {
+
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+
+        @ApiModelProperty("专辑名称")
+        private String name;
+
+
+        @ApiModelProperty("专辑介绍")
+        private String describe;
+
+
+        @ApiModelProperty("专辑封面")
+        private String coverImg;
+
+
+        @ApiModelProperty("曲目数")
+        private Integer musicNum;
+
+
+        @ApiModelProperty("平台价格")
+        private BigDecimal originalPrice;
+
+
+        @ApiModelProperty("机构价格")
+        private BigDecimal salePrice;
+
+
+        @ApiModelProperty("购买周期")
+        private Integer purchaseCycle;
+
+
+        @ApiModelProperty("曲目声部分类(多个,分隔)")
+        private String subjectTypes;
+
+
+        @ApiModelProperty("启用状态")
+        private Boolean status;
+
+
+        @ApiModelProperty("删除标识")
+        private Boolean delFlag;
+
+
+        @ApiModelProperty("更新时间")
+        private Date updateTime;
+
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static TenantAlbum from(String json) {
+            return JSON.parseObject(json, TenantAlbum.class);
+        }
+    }
+}

+ 76 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderDetailVo.java

@@ -0,0 +1,76 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import com.alibaba.fastjson.JSON;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 订单详情表
+ * 2022-12-20 19:09:34
+ */
+@ApiModel(value = "UserPaymentOrderDetailVo对象", description = "订单详情表查询视图对象")
+public class UserPaymentOrderDetailVo {
+
+    @Data
+    @ApiModel(" UserPaymentOrderDetail-订单详情表")
+    public static class UserPaymentOrderDetail {
+
+		@ApiModelProperty("主键ID")
+        private Long id;
+
+		@ApiModelProperty("支付订单ID")
+        private Long userPaymentOrderId;
+
+		@ApiModelProperty("订单号")
+        private String orderNo;
+
+		@ApiModelProperty("商品类型:  VIP、开通会员 ")
+        private String goodsType;
+
+		@ApiModelProperty("商品名称")
+        private String goodsName;
+
+		@ApiModelProperty("商品图片")
+        private String goodsUrl;
+
+        @ApiModelProperty("商品Id")
+        private String goodsId;
+
+        @ApiModelProperty("商品来源")
+        private String goodsSource;
+
+		@ApiModelProperty("原价")
+        private BigDecimal originalPrice;
+
+		@ApiModelProperty("现价")
+        private BigDecimal currentPrice;
+
+		@ApiModelProperty("实付现金")
+        private BigDecimal paymentCashAmount;
+
+		@ApiModelProperty("优惠金额")
+        private BigDecimal paymentCouponAmount;
+
+		@ApiModelProperty("商品数量")
+        private Integer goodsNum;
+
+		@ApiModelProperty("更新时间")
+        private Date updateTime;
+
+		@ApiModelProperty("下单时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserPaymentOrderDetail from(String json) {
+            return JSON.parseObject(json, UserPaymentOrderDetail.class);
+        }
+    }
+
+}

+ 232 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/tenant/vo/UserPaymentOrderVo.java

@@ -0,0 +1,232 @@
+package com.yonge.cooleshow.tenant.vo;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.OrderTypeEnum;
+import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 平台订单表
+ * 2022-12-20 19:09:34
+ */
+@ApiModel(value = "UserPaymentOrderVo对象", description = "平台订单表查询视图对象")
+public class UserPaymentOrderVo {
+
+    @Data
+    @ApiModel(" UserPaymentOrder-平台订单表")
+    public static class UserPaymentOrder {
+
+
+		@ApiModelProperty("主键")
+        private Long id;
+
+		@ApiModelProperty("支付厂商")
+        private String paymentVender;
+
+		@ApiModelProperty("支付渠道")
+        private String paymentChannel;
+
+		@ApiModelProperty("用户身份")
+        private String paymentClient;
+
+		@ApiModelProperty("用户编号")
+        private Long userId;
+
+		@ApiModelProperty("商户订单号")
+        private String orderNo;
+
+		@ApiModelProperty("交易流水号")
+        private String transNo;
+
+		@ApiModelProperty("业务类型Id")
+        private String bizId;
+
+		@ApiModelProperty("订单支付类型")
+        private String orderType;
+
+		@ApiModelProperty("订单状态")
+        private String status;
+
+		@ApiModelProperty("原价")
+        private BigDecimal originalPrice;
+
+		@ApiModelProperty("现价")
+        private BigDecimal currentPrice;
+
+		@ApiModelProperty("支付现金金额")
+        private BigDecimal paymentCashAmount;
+
+		@ApiModelProperty("支付优惠金额")
+        private BigDecimal paymentCouponAmount;
+
+		@ApiModelProperty("支付通道费用")
+        private BigDecimal paymentChannelFee;
+
+		@ApiModelProperty("订单名称")
+        private String orderName;
+
+		@ApiModelProperty("订单描述信息")
+        private String orderDesc;
+
+		@ApiModelProperty("用户备注")
+        private String userNote;
+
+		@ApiModelProperty("支付时间")
+        private Date payTime;
+
+		@ApiModelProperty("原因")
+        private String errorMsg;
+
+		@ApiModelProperty("收货地址")
+        private Long receiveAddress;
+
+		@ApiModelProperty("更新时间")
+        private Date updateTime;
+
+		@ApiModelProperty("下单时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserPaymentOrder from(String json) {
+            return JSON.parseObject(json, UserPaymentOrder.class);
+        }
+
+
+        public UserPaymentOrder userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+
+        public UserPaymentOrder paymentClient(String paymentClient) {
+            this.paymentClient = String.valueOf(paymentClient);
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("下单请求对象")
+    public static class OrderReq implements Serializable {
+
+        @ApiModelProperty("支付类型: adapay")
+        private String paymentType;
+
+        @ApiModelProperty("业务类型Id")
+        private String bizId;
+
+        @NotNull(message = "订单类型不能为空")
+        @ApiModelProperty(value = "订单类型: 学生端( VIP、开通会员  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名 ) 老师端(VIP、开通会员 PIANO_ROOM、琴房时长 ACTI_REGIST 活动报名)", required = true)
+        private OrderTypeEnum orderType;
+
+        @ApiModelProperty("现价")
+        private BigDecimal currentPrice;
+
+        @ApiModelProperty("支付现金金额")
+        private BigDecimal paymentCashAmount;
+
+        @ApiModelProperty("支付优惠金额")
+        private BigDecimal paymentCouponAmount;
+
+        @ApiModelProperty("订单名称")
+        private String orderName;
+
+        @ApiModelProperty("订单描述信息")
+        private String orderDesc;
+
+        @ApiModelProperty("用户备注")
+        private String userNote;
+
+        @ApiModelProperty("优惠券Id;多个使用,隔开")
+        private String couponIds;
+
+        @ApiModelProperty("订单商品信息")
+        private List<UserPaymentOrderWrapper.OrderGoodsInfo> goodsInfos;
+
+        @ApiModelProperty(value = "用户身份", hidden = true)
+        private String paymentClient;
+
+        @ApiModelProperty(value = "用户编号", hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "推荐用户id(有推荐人的情况)")
+        private Long recomUserId;
+
+        @ApiModelProperty(value = "活动id")
+        private Long activityId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public OrderReq paymentClient(String paymentClient) {
+            this.paymentClient = String.valueOf(paymentClient);
+            return this;
+        }
+
+        public OrderReq userId(String userId) {
+            this.userId = Long.parseLong(userId);
+            return this;
+        }
+    }
+
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel("订单支付参数配置")
+    public static class PaymentReqConfig implements Serializable {
+
+        @ApiModelProperty("支付渠道")
+        private String paymentChannel;
+
+        @ApiModelProperty("商户订单号")
+        private String merOrderNo;
+
+        @ApiModelProperty("商品名称")
+        private String subject;
+
+        @ApiModelProperty("商品描述")
+        private String body;
+
+        @ApiModelProperty("附加信息")
+        private String addition;
+
+        @ApiModelProperty("价格")
+        private BigDecimal price;
+
+        @ApiModelProperty("银行卡类型")
+        private String bankType;
+
+        @ApiModelProperty("微信授权code")
+        private String code;
+
+        @ApiModelProperty("订单过期时间")
+        private Date expirationTime;
+
+        @ApiModelProperty("微信支付公众号")
+        private String wxAppId;
+
+        @ApiModelProperty(value = "支付用户Id", hidden = true)
+        private String userId;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+    }
+}

+ 79 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseCoursewareController.java

@@ -0,0 +1,79 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseCoursewareSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseCourseware;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseCoursewareService;
+import com.yonge.cooleshow.biz.dal.vo.CourseCoursewareVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/courseCourseware")
+@Api(value = "课件表", tags = "课件表")
+public class CourseCoursewareController extends BaseController {
+
+	@Autowired
+	private CourseCoursewareService courseCoursewareService;
+
+	/**
+	 * 查询分页
+	 */
+	@PostMapping("/page")
+	@ApiOperation(value = "查询分页", notes = "传入courseCoursewareSearch")
+	public HttpResponseResult<PageInfo<CourseCoursewareVo>> page(@RequestBody CourseCoursewareSearch query) {
+		IPage<CourseCoursewareVo> pages = courseCoursewareService.selectPage(PageUtil.getPage(query), query);
+		return succeed(PageUtil.pageInfo(pages));
+	}
+
+	/**
+	 * 新增或修改
+	 */
+	@PostMapping("/submit")
+	@ApiOperation(value = "新增或修改", notes = "传入courseCourseware")
+	public HttpResponseResult<CourseCourseware> submit(@Valid @RequestBody CourseCourseware courseCourseware) {
+		if (courseCourseware.getId() != null) {
+			courseCourseware.setUpdateTime(new Date());
+		} else {
+			courseCourseware.setUpdateTime(new Date());
+			courseCourseware.setCreateTime(new Date());
+		}
+		courseCourseware.setClientType(ClientEnum.TEACHER);
+		return succeed(courseCoursewareService.submit(courseCourseware));
+	}
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove/{id}")
+	@ApiOperation(value = "删除", notes = "传入id")
+	public HttpResponseResult remove(@PathVariable Long id ) {
+		return status(courseCoursewareService.removeById(id));
+	}
+
+
+	/**
+	 * 删除
+	 */
+	@PostMapping("/remove")
+	@ApiOperation(value = "批量删除", notes = "传入id")
+	public HttpResponseResult remove(@RequestParam String ids ) {
+		return status(courseCoursewareService.removeByIds(StringUtil.toLongList(ids)));
+	}
+}

+ 109 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/CourseGroupController.java

@@ -0,0 +1,109 @@
+package com.yonge.cooleshow.website.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
+import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.vo.CourseGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.LiveCourseInfoVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 课程组表(CourseGroup)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:29:10
+ */
+@Api(tags = "课程组表")
+@RestController
+@RequestMapping("${app-config.url.website:}/courseGroup")
+public class CourseGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private CourseGroupService courseGroupService;
+
+    @ApiOperation("直播课详情")
+    @GetMapping("/queryLiveCourseInfo")
+    public HttpResponseResult<LiveCourseInfoVo> queryLiveCourseInfo(@ApiParam(value = "课程组id", required = true) @RequestParam(value = "groupId") Long groupId) {
+        return succeed(courseGroupService.queryLiveCourseInfo(groupId));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "teacherId", dataType = "Long", value = "老师id"),
+            @ApiImplicitParam(name = "search", dataType = "String", value = "关键字"),
+            @ApiImplicitParam(name = "groupStatus", dataType = "String", value = "课程组状态  ING(进行中)  NOT_SALE(未开售,未上架) APPLY(报名中,销售中) COMPLETE(已完成)"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+    })
+    @ApiOperation("分页查询直播课课程组列表")
+    @PostMapping("/queryPageCourseGroup")
+    public HttpResponseResult<PageInfo<CourseGroupVo>> queryPageLiveCourseGroup(@RequestBody Map<String, Object> param) {
+        return succeed(courseGroupService.queryPageLiveCourseGroup(param));
+    }
+
+    @ApiOperation("创建直播课程组-新增课程组")
+    @PostMapping("/addLiveCourse")
+    public HttpResponseResult<Object> addLiveCourse(@RequestBody LiveCourseGroupDto dto) {
+        if (dto.getCoursePrice().compareTo(BigDecimal.ZERO) <= 0) {
+            return failed("课程价格不能为0元");
+        }
+        courseGroupService.addLiveCourse(dto);
+        return succeed();
+    }
+
+    @ApiOperation("创建直播课程组-锁定课程时间-将课时写到缓存当作锁定的时间")
+    @PostMapping("/lockCourseToCache")
+    public HttpResponseResult<List<CourseTimeEntity>> lockCourseToCache(@RequestBody CheckCourseTimeDto dto) {
+        return succeed(courseGroupService.lockCourseToCache(dto));
+    }
+
+    @ApiOperation("创建直播课程组-解除锁定课程时间-删除写到缓存当作锁定的课时")
+    @GetMapping("/unlockCourseToCache")
+    public HttpResponseResult<Object> unlockCourseToCache(@RequestParam("teacherId") Long teacherId) {
+        courseGroupService.unlockCourseToCache(teacherId);
+        return succeed();
+    }
+
+    @ApiOperation("取消课程组-下架课程组")
+    @GetMapping("/cancelCourseGroup")
+    public HttpResponseResult<Object> cancelCourseGroup(@RequestParam("groupId") Long groupId) {
+        courseGroupService.cancelCourseGroup(groupId);
+        return succeed();
+    }
+
+    @ApiOperation("获取老师排直播课时锁定的课时")
+    @GetMapping("/getLockCache")
+    public HttpResponseResult<Object> getLockCache(@RequestParam("teacherId") Long teacherId) {
+        return succeed(courseGroupService.getLiveLockTimeCache(teacherId).get(teacherId));
+    }
+
+
+    @ApiOperation("修改直播课程组")
+    @PostMapping("/updateLiveCourse")
+    public HttpResponseResult<Object> updateLiveCourse(@RequestBody LiveCourseGroupDto dto) {
+        courseGroupService.updateLiveCourse(dto);
+        return succeed();
+    }
+}
+

+ 45 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/LiveRoomVideoController.java

@@ -0,0 +1,45 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.LiveRoomVideo;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomVideoService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 直播视频记录(LiveRoomVideo)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:41:17
+ */
+@Api(tags = "直播视频记录")
+@RestController
+@RequestMapping("${app-config.url.website:}/liveRoomVideo")
+public class LiveRoomVideoController extends BaseController {
+
+    private final static Logger log = LoggerFactory.getLogger(LiveRoomVideoController.class);
+
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private LiveRoomVideoService liveRoomVideoService;
+
+    @ApiOperation("查询直播回放")
+    @GetMapping("/queryVideo")
+    public HttpResponseResult<List<LiveRoomVideo>> queryVideo(@ApiParam(value = "房间uid", required = true) String roomUid) {
+        return succeed(liveRoomVideoService.queryVideo(roomUid));
+    }
+
+}
+

+ 124 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/MusicAlbumController.java

@@ -0,0 +1,124 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicAlbumSearch;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
+import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+
+/**
+ * 专辑表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.website:}/music/album")
+@Api(tags = "专辑接口")
+public class MusicAlbumController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicAlbumService musicAlbumService;
+
+    /**
+     * 专辑收藏
+     */
+    @PostMapping("/favorite/{id}")
+    @ApiOperation(value = "专辑收藏/取消收藏")
+    public HttpResponseResult<Boolean> favorite(@ApiParam(value = "专辑编号", required = true) @PathVariable("id") Long id,
+                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        return succeed(musicAlbumService.setFavorite(sysUser.getId(), id, ClientEnum.valueOf(clientType)));
+    }
+
+
+    /**
+     * 专辑收藏
+     */
+    @GetMapping("/favorite")
+    @ApiOperation(value = "学生-收藏专辑列表")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> favoriteAlbum(@ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType,
+                                                                    QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        StudentMusicAlbumSearch search = new StudentMusicAlbumSearch();
+        search.studentId(sysUser.getId())
+                .albumFavorite(true)
+                .setAlbumStatus(YesOrNoEnum.YES);
+
+        IPage<MusicAlbumVo> albumVoIPage = musicAlbumService.favoriteAlbum(PageUtil.getPage(query), search, ClientEnum.valueOf(clientType));
+        return succeed(PageUtil.pageInfo(albumVoIPage));
+    }
+
+    /**
+     * 已购买专辑信息
+     * @return HttpResponseResult<PageInfo<MusicAlbumVo>>
+     */
+    @ApiOperation(value = "已购买专辑信息")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "clientType", value = "客户端类型: TEACHER, STUDENT; 默认值: STUDENT"),
+            @ApiImplicitParam(name = "gift", value = "课程赠品 0:购买 1:赠品, 默认值: 0"),
+            @ApiImplicitParam(name = "page", value = "分页查询, 默认值: 1"),
+            @ApiImplicitParam(name = "row", value = "当前页行数, 默认值: 10"),
+    })
+    @GetMapping("/purchased")
+    public HttpResponseResult<PageInfo<MusicAlbumVo>> purchasedAlbumInfo(@RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType,
+                                                                         @RequestParam(value = "gift", required = false, defaultValue = "0") Integer gift,
+                                                                         QueryInfo query) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        StudentMusicAlbumSearch search = new StudentMusicAlbumSearch();
+        search.studentId(sysUser.getId())
+                .albumPurchased(true)
+                .purchaseType(PurchaseRecordTypeEnum.ALBUM)
+                .courseGift(gift)
+                .orderStatus(OrderStatusEnum.PAID)
+                .clientType(ClientEnum.valueOf(clientType));
+
+        IPage<MusicAlbumVo> albumVoIPage = musicAlbumService.favoriteAlbum(PageUtil.getPage(query), search, ClientEnum.valueOf(clientType));
+        return succeed(PageUtil.pageInfo(albumVoIPage));
+    }
+}

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

@@ -0,0 +1,253 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetDto;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicSheetRelatedQueryInfo;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.StudentMusicSheetSearch;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.ChargeTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.album.PurchaseRecordTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherAuditMusicSheetVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.EStatus;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.website:}/music/sheet")
+@Api(tags = "曲谱接口")
+public class MusicSheetController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetService musicSheetService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    /**
+     * 曲目收藏
+     */
+    @PostMapping("/favorite/{id}")
+    @ApiOperation(value = "曲目收藏/取消收藏")
+    public HttpResponseResult<Boolean> favorite(@ApiParam(value = "曲目编号", required = true) @PathVariable("id") Long id,
+                                                @ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        return succeed(musicSheetService.setFavorite(sysUser.getId(), id, ClientEnum.valueOf(clientType)));
+    }
+
+
+    /**
+     * 我的单曲,收藏单曲
+     */
+    @ApiOperation(value = "学生-我的单曲")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "clientType", value = "客户端类型 TEACHER, STUDENT, 默认值: STUDENT"),
+            @ApiImplicitParam(name = "gift", value = "课程赠品 0:购买 1:赠品, 默认值: 0"),
+            @ApiImplicitParam(name = "page", value = "分页查询, 默认值: 1"),
+            @ApiImplicitParam(name = "row", value = "当前页行数, 默认值: 10"),
+    })
+    @GetMapping("/my")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> myMusic(@RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType,
+                                                              @RequestParam(value = "gift", required = false, defaultValue = "0") Integer gift,
+                                                              QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setStudentId(sysUser.getId());
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        search.setUserType(ClientEnum.valueOf(clientType));
+        search.setPurchaseType(Optional.ofNullable(search.getPurchaseType()).orElse(PurchaseRecordTypeEnum.MUSIC));
+        search.setCourseGift(Optional.ofNullable(search.getCourseGift()).orElse(EStatus.DISABLE.getValue()));
+
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.myMusic(PageUtil.getPage(query),search);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+
+
+    /**
+     * 我的单曲,收藏单曲
+     */
+    @GetMapping("/favorite")
+    @ApiOperation(value = "学生-收藏单曲")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> favoriteMusic(@ApiParam(value = "客户端类型") @RequestParam(value = "clientType", required = false, defaultValue = "STUDENT") String clientType,
+                                                                    QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ClientEnum.invalid(clientType)) {
+            return failed("无效的客户端类型");
+        }
+
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setStudentId(sysUser.getId());
+        search.setState(YesOrNoEnum.YES);
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.favoriteMusic(PageUtil.getPage(query),search, ClientEnum.valueOf(clientType));
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+    @ApiOperation(value = "老师-个人中心-曲目分页查询", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/teacher/list", consumes="application/json", produces="application/json")
+    public HttpResponseResult<TeacherAuditMusicSheetVo> list(@RequestBody MusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 设置只查老师用户 状态为启用
+        query.setCreateBy(sysUser.getId());
+        if (query.getAuditStatus() != null && AuthStatusEnum.PASS.getCode().equals(query.getAuditStatus().getCode())) {
+            query.setState(YesOrNoEnum.YES);
+        } else if (query.getAuditStatus() != null && AuthStatusEnum.OUT_SALE.getCode().equals(query.getAuditStatus().getCode())) {
+            query.setState(YesOrNoEnum.NO);
+            query.setAuditStatus(AuthStatusEnum.PASS);
+        }
+        query.setSourceType(SourceTypeEnum.TEACHER);
+        query.setMyself(true);
+
+        IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.selectPage(PageUtil.getPage(query), query);
+
+        TeacherAuditMusicSheetVo teacherAuditMusicSheetVo = musicSheetService.selectTeacherCount(sysUser.getId());
+        if (teacherAuditMusicSheetVo == null) {
+            teacherAuditMusicSheetVo = new TeacherAuditMusicSheetVo();
+        }
+        teacherAuditMusicSheetVo.setList(PageUtil.pageInfo(musicSheetVoIPage));
+        return succeed(teacherAuditMusicSheetVo);
+    }
+
+    @ApiOperation(value = "老师新增曲目", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/create", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> create(@Valid @RequestBody MusicSheetDto musicSheetDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (ChargeTypeEnum.CHARGE.getCode().equals(musicSheetDto.getChargeType().getCode())
+                && musicSheetDto.getMusicPrice()==null){
+            return failed("此曲谱为收费曲谱,需要提供价格");
+        }
+
+        musicSheetDto.setUserId(sysUser.getId());
+        musicSheetDto.setAuditStatus(AuthStatusEnum.DOING);
+        musicSheetDto.setSubmitAuditTime(new Date());
+        musicSheetDto.setSourceType(SourceTypeEnum.TEACHER);
+
+        musicSheetDto.setFavoriteCount(0);
+        musicSheetDto.setCreateBy(sysUser.getId());
+        musicSheetDto.setCreateTime(new Date());
+        musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
+        return succeed("新增曲谱成功");
+    }
+
+    /**
+     * 启用/停用
+     */
+    @PostMapping("/state/{id}")
+    @ApiOperation(value = "启用/停用", notes = "传入id")
+    public HttpResponseResult<Boolean> state(@ApiParam(value = "曲目编号", required = true)  @PathVariable Long id) {
+        if (StringUtil.isEmpty(id)) {
+            return failed("参数不能为空");
+        }
+        MusicSheet musicSheet = musicSheetService.getById(id);
+        if (musicSheet == null) {
+            return failed("未找到曲目");
+        }
+
+        if (musicSheet.getState().equals(YesOrNoEnum.NO)) {
+            return failed("曲目已被下架");
+        }
+        return status(musicSheetService.state(id,"", ClientEnum.TEACHER));
+    }
+
+
+    @ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/update", consumes="application/json", produces="application/json")
+    public HttpResponseResult<Object> update(@Valid @RequestBody MusicSheetDto musicSheet) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (musicSheet.getId()==null){
+            return failed("缺少ID");
+        }
+
+        musicSheet.setUserId(sysUser.getId());
+        musicSheet.setSubmitAuditTime(new Date());
+        musicSheet.setCreateTime(new Date());
+        musicSheet.setCreateBy(sysUser.getId());
+        musicSheet.setUpdateBy(sysUser.getId());
+        musicSheet.setUpdateTime(new Date());
+        musicSheet.setSubmitAuditTime(new Date());
+        musicSheet.setAuditStatus(AuthStatusEnum.DOING);
+        if ( musicSheetService.saveMusicSheet(musicSheet,sysUser.getId())){
+            return succeed("修改成功");
+        } else {
+            return failed("修改失败");
+        }
+    }
+
+    @ApiOperation(value = "关联的曲目列表")
+    @GetMapping(value="/queryRelatedList")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> queryRelatedList(MusicSheetRelatedQueryInfo queryInfo) {
+    	
+    	IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.queryRelatedList(PageUtil.getPage(queryInfo),queryInfo.getAlbumId(), queryInfo.getMusicSheetId());
+        return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+    }
+}

+ 88 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/SmsCodeController.java

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.wf.captcha.SpecCaptcha;
+import com.wf.captcha.utils.CaptchaUtil;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.security.SecurityConstants;
+import com.yonge.toolset.base.exception.BizException;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/code")
+@Api(tags = "验证码服务")
+public class SmsCodeController extends BaseController {
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+    @ApiOperation(value = "发送登录短信验证码")
+    @ApiImplicitParams({@ApiImplicitParam(name = "mobile", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String")})
+    @PostMapping(value = "/sendSmsCode")
+    public Object sendLoginVerifyCode(String mobile, String type) throws Exception {
+        smsCodeService.sendValidCode(mobile, type, ClientEnum.WEBSITE);
+        return succeed();
+    }
+
+    @ApiOperation(value = "校验短信验证码")
+    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "短信验证码", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "type", value = "类型(PASSWD:修改密码,LOGIN:登录或注册,BANK:绑定银行卡,PHONE:修改手机号)", required = true, dataType = "String")})
+    @PostMapping(value = "/verifySmsCode")
+    public Object verifySmsCode(String phone, String code, String type) {
+        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        if (smsCodeService.verifyValidCode(phone, code, type)) {
+            return succeed();
+        }
+        return failed("验证码校验失败");
+    }
+
+    @PostMapping(value = "/verifyImageCode")
+    @ApiOperation("校验登录图形验证码")
+    @ApiImplicitParams({@ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "code", value = "验证码", required = true, dataType = "String")})
+    public Object verifyImageCode(String phone, String code) {
+        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
+            return failed(SecurityConstants.PARAM_VERIFY_EXCEPTION);
+        }
+        String redisKey = MessageTypeEnum.KAPTCHA_SESSION_KEY + phone;
+        if (redisTemplate.hasKey(redisKey)) {
+            if (StringUtils.equalsIgnoreCase(redisTemplate.opsForValue().get(redisKey), code)) {
+                return succeed();
+            }
+        }
+        return failed(SecurityConstants.VERIFY_FAILURE);
+    }
+
+    @RequestMapping("/getImageCode")
+    @ApiOperation("获取登录图片验证码")
+    @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String")
+    public void getLoginImage(HttpServletRequest request, HttpServletResponse response, String phone) throws Exception {
+        if (StringUtils.isEmpty(phone)) {
+            throw new BizException("请输入手机号");
+        }
+        SpecCaptcha specCaptcha = new SpecCaptcha(125, 45, 4);
+        redisTemplate.opsForValue().set(MessageTypeEnum.KAPTCHA_SESSION_KEY + phone, specCaptcha.text(), 3, TimeUnit.MINUTES);
+        CaptchaUtil.out(specCaptcha, request, response);
+    }
+}

+ 118 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/StudentController.java

@@ -0,0 +1,118 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.StudentStarService;
+import com.yonge.cooleshow.biz.dal.vo.MyFollow;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/student")
+@Api(value = "学生表", tags = "学生表")
+public class StudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+    @Autowired
+    private StudentStarService studentStarService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "查询学员")
+    @GetMapping("/queryUser")
+    public HttpResponseResult<Student> queryUser() throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        Student student = studentService.getById(user.getId());
+        return succeed(student);
+    }
+
+    @ApiOperation(value = "查询学员基本信息")
+    @GetMapping("/queryUserInfo")
+    public HttpResponseResult<StudentHomeVo> queryUserInfo() throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(studentService.queryUserInfo(user));
+    }
+
+    @ApiOperation(value = "设置声部")
+    @GetMapping("/setSubject")
+    public HttpResponseResult setSubject(@ApiParam(value = "声部主键集合", required = true) @RequestParam("subjectIds") String subjectIds) {
+        if (StringUtil.isEmpty(subjectIds)) {
+            return failed("参数不能为空");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(studentService.setSubject(user.getId(), subjectIds) > 0);
+    }
+
+    @ApiOperation(value = "获取声部搜索下拉框")
+    @PostMapping("/querySubjectItem")
+    public HttpResponseResult<List<Subject>> querySubjectItem(
+            @ApiParam(value = "类型 PRACTICE 陪练课 LIVE 直播课 VIDEO 视频课 PIANO_ROOM 琴房 MUSIC 曲目 ") String type) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(studentService.querySubjectItem(user.getId(),type));
+    }
+
+    @ApiOperation(value = "我的关注")
+    @PostMapping(value = "/queryMyFollow")
+    public HttpResponseResult<PageInfo<MyFollow>> queryMyFollow(@RequestBody QueryMyFollowSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(sysUser.getId());
+        IPage<MyFollow> pages = studentService.queryMyFollow(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "关注/取消关注")
+    @GetMapping("/starOrUnStar")
+    public HttpResponseResult<Boolean> starOrUnStar(@ApiParam(value = "老师ID", required = true) @RequestParam("userId") Long userId,
+                                                    @ApiParam(value = "状态 0 取消关注 1 关注", required = true) @RequestParam("starStatus") Integer starStatus) {
+        if (null == userId) {
+            return failed("缺少老师ID");
+        }
+        YesOrNoEnum starStatusEnum = YesOrNoEnum.valueOf(starStatus);
+        if (null == starStatusEnum) {
+            return failed("缺少关注状态");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return studentStarService.starOrUnStar(user.getId(), userId, starStatusEnum);
+    }
+}

+ 74 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/SysConfigController.java

@@ -0,0 +1,74 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/** 
+ * 系统配置控制层
+ */
+@RestController
+@Api(tags = "系统参数设置")
+@RequestMapping(value = "${app-config.url.website:}/sysConfig")
+public class SysConfigController extends BaseController {
+
+	@Autowired
+	private SysConfigService sysConfigService;
+
+	@ApiOperation(value = "参数列表")
+	@GetMapping(value = "list")
+	public Object configList(String group) {
+		Map<String,Object> params = new HashMap<String, Object>();
+		params.put("group", group);
+		List<SysConfig> configs = sysConfigService.findAll(params);
+		return succeed(configs);
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "get")
+	public Object getConfig(Long id) {
+		if (id == null || id <= 0)
+			return failed("请检查输入的ID");
+		return succeed(sysConfigService.get(id));
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "queryByParamName")
+	public Object queryByParamName(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findByParamName(paramName));
+	}
+
+	@GetMapping(value = "findConfigValue")
+	public HttpResponseResult<String> findConfigValue(String paramName) {
+		if(StringUtils.isBlank(paramName)){
+			return failed("参数不能为空");
+		}
+		return succeed(sysConfigService.findConfigValue(paramName));
+	}
+
+	@ApiOperation(value = "查询参数")
+	@GetMapping(value = "queryByParamNameList")
+	public Object queryByParamNameList(String paramNames) {
+		if(StringUtils.isBlank(paramNames)){
+			return failed("参数不能为空");
+		}
+		List<String> paramNameList = Arrays.asList(paramNames.split(","));
+		return succeed(sysConfigService.findByParamName(paramNameList));
+	}
+}

+ 52 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherAuthEntryRecordController.java

@@ -0,0 +1,52 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.req.TeacherApplyDetailReq;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthEntryRecordService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherAuthEntryRecordVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/teacherAuthEntryRecord")
+@Api(value = "老师入驻审核表", tags = "老师入驻审核表")
+public class TeacherAuthEntryRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthEntryRecordService teacherAuthEntryRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @GetMapping("/getLastRecordByUserId")
+    @ApiOperation(value = "获取最近一次提交的申请内容")
+    public HttpResponseResult<TeacherAuthEntryRecordVo> getLastRecordByUserId() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        TeacherAuthEntryRecordVo detail = teacherAuthEntryRecordService.getLastRecordByUserId(user.getId());
+        return succeed(detail);
+    }
+
+    @PostMapping("/doApply")
+    @ApiOperation(value = "提交申请", notes = "传入teacherAuthEntryRecord")
+    public HttpResponseResult<Boolean> doApply(@Valid @RequestBody TeacherApplyDetailReq teacherApplyDetailDto) throws Exception {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        //处理老师申请逻辑
+        return teacherAuthEntryRecordService.doApply(teacherApplyDetailDto, user);
+    }
+}

+ 49 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherAuthMusicianRecordController.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.TeacherAuthMusicianRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/teacherAuthMusicianRecord")
+@Api(value = "老师音乐人审核表", tags = "老师音乐人审核表")
+public class TeacherAuthMusicianRecordController extends BaseController {
+    @Autowired
+    private TeacherAuthMusicianRecordService teacherAuthMusicianRecordService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 获取音乐人审核状态
+     */
+    @GetMapping("/getMusicianAuthStatus")
+    @ApiOperation(value = "获取音乐人审核状态")
+    public HttpResponseResult<AuthStatusEnum> getMusicianAuthStatus() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        AuthStatusEnum musicianAuthStatus = teacherAuthMusicianRecordService.getMusicianAuthStatus(user.getId());
+        return succeed(musicianAuthStatus);
+    }
+
+    @PostMapping("/doApply")
+    @ApiOperation(value = "提交申请", notes = "传入teacherAuthEntryRecord")
+    public HttpResponseResult<Boolean> doApply() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        //处理老师申请逻辑
+        return teacherAuthMusicianRecordService.doApply(sysUser.getId());
+    }
+
+}

+ 153 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherController.java

@@ -0,0 +1,153 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.TeacherDto;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.service.StudentStarService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.vo.MyFens;
+import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.base.page.QueryInfo;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.website:}/teacher")
+@Api(value = "教师表", tags = "教师表")
+public class TeacherController extends BaseController {
+    @Autowired
+    private TeacherService teacherService;
+    @Autowired
+    private StudentStarService studentStarService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "我的-查询教师基本信息")
+    @GetMapping("/queryUserInfo")
+    public HttpResponseResult<TeacherHomeVo> queryUserInfo() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return teacherService.queryUserInfo(user.getId());
+    }
+
+    @ApiOperation(value = "开通直播")
+    @GetMapping("/openLive")
+    public HttpResponseResult<Boolean> openLive() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return teacherService.openLive(user.getId());
+    }
+
+    @ApiOperation(value = "获取老师可授课声部列表")
+    @PostMapping("/querySubject")
+    public HttpResponseResult<List<Subject>> querySubject() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(teacherService.querySubject(user.getId()));
+    }
+
+    @ApiOperation(value = "设置声部")
+    @GetMapping("/setSubject")
+    public HttpResponseResult setSubject(@ApiParam(value = "声部主键集合", required = true) @RequestParam("subjectIds") String subjectIds) {
+        if (StringUtil.isEmpty(subjectIds)) {
+            return failed("参数不能为空");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return status(teacherService.setSubject(user.getId(), subjectIds) > 0);
+    }
+
+    @ApiOperation(value = "获取声部搜索下拉框")
+    @PostMapping("/querySubjectItem")
+    public HttpResponseResult<List<Subject>> querySubjectItem(
+            @ApiParam(value = "类型 PRACTICE 陪练课 LIVE 直播课 VIDEO 视频课 PIANO_ROOM 琴房 MUSIC 曲目 ") String type) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(teacherService.querySubjectItem(user.getId(), type));
+    }
+
+    @ApiOperation(value = "我的-个人风采")
+    @GetMapping("/queryTeacherStyle")
+    public HttpResponseResult<TeacherVo> queryTeacherStyle() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return HttpResponseResult.succeed(teacherService.detail(user.getId()));
+    }
+
+    @ApiOperation(value = "我的-个人风采保存")
+    @PostMapping("/saveTeacherStyle")
+    public HttpResponseResult<TeacherVo> saveTeacherStyle(@RequestBody TeacherDto teacherDto) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtil.isEmpty(teacherDto.getSubjectId())) {
+            return failed("参数异常");
+        }
+        teacherDto.setUserId(user.getId());
+        return teacherService.saveTeacherStyle(teacherDto);
+    }
+
+    @ApiOperation(value = "我的粉丝")
+    @PostMapping(value = "/queryMyFans")
+    public HttpResponseResult<PageInfo<MyFens>> queryMyFans(@RequestBody QueryInfo query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || sysUser.getId() == null) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        IPage<MyFens> pages = teacherService.queryMyFans(PageUtil.getPage(query), sysUser.getId());
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "关注/取消关注")
+    @GetMapping("/starOrUnStar")
+    public HttpResponseResult<Boolean> starOrUnStar(@ApiParam(value = "老师ID", required = true) @RequestParam("userId") Long userId,
+                                                    @ApiParam(value = "状态 0 取消关注 1 关注", required = true) @RequestParam("starStatus") Integer starStatus) {
+        if (null == userId) {
+            return failed("缺少老师ID");
+        }
+        YesOrNoEnum starStatusEnum = YesOrNoEnum.valueOf(starStatus);
+        if (null == starStatusEnum) {
+            return failed("缺少关注状态");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return studentStarService.starOrUnStar(user.getId(), userId, starStatusEnum);
+    }
+
+}

+ 63 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/website/controller/TeacherFreeTimeController.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.website.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.PracticeTimesSetting;
+import com.yonge.cooleshow.biz.dal.entity.TeacherFreeTime;
+import com.yonge.cooleshow.biz.dal.service.TeacherFreeTimeService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherFreeTimeVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ * 老师可排课时间表(TeacherFreeTime)表控制层
+ *
+ * @author zx
+ * @since 2022-03-25 10:04:26
+ */
+@Api(tags = "老师可排课时间表")
+@RestController
+@RequestMapping("${app-config.url.website:}/teacherFreeTime")
+public class TeacherFreeTimeController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Autowired
+    private TeacherFreeTimeService teacherFreeTimeService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "新增、修改老师陪练课设置")
+    @PostMapping("/upSet")
+    public HttpResponseResult upSet(@Valid @RequestBody TeacherFreeTime teacherFreeTime){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        teacherFreeTime.setTeacherId(user.getId());
+        teacherFreeTimeService.upSet(teacherFreeTime);
+        return succeed();
+    }
+
+    @ApiOperation(value = "获取老师陪练课设置")
+    @PostMapping("/getDetail")
+    public HttpResponseResult<TeacherFreeTimeVo> getDetail(@RequestBody PracticeTimesSetting practiceTimesSetting){
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        practiceTimesSetting.setUserId(user.getId());
+        return succeed(teacherFreeTimeService.getDetail(practiceTimesSetting));
+    }
+}
+

Vissa filer visades inte eftersom för många filer har ändrats