浏览代码

fix单体服务布署

Eric 1 年之前
父节点
当前提交
95e5696255
共有 44 个文件被更改,包括 4964 次插入0 次删除
  1. 115 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/CourseHomeworkController.java
  2. 103 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupController.java
  3. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupMemberAuditController.java
  4. 93 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupMemberController.java
  5. 46 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupNoticeController.java
  6. 102 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImUserFriendController.java
  7. 58 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MemberPriceSettingsController.java
  8. 206 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicAlbumController.java
  9. 405 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java
  10. 34 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicTagController.java
  11. 50 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/PaymentController.java
  12. 88 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SmsCodeController.java
  13. 148 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentActivityController.java
  14. 172 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java
  15. 100 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseGroupController.java
  16. 194 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentCourseScheduleController.java
  17. 92 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomController.java
  18. 45 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomVideoController.java
  19. 59 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SubjectController.java
  20. 82 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysConfigController.java
  21. 47 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysImComplaintController.java
  22. 131 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysMessageController.java
  23. 83 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysMusicCompareRecordController.java
  24. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java
  25. 84 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysUserContractRecordController.java
  26. 146 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TeacherController.java
  27. 80 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantActivationCodeController.java
  28. 89 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumController.java
  29. 68 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumSheetController.java
  30. 80 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UploadFileController.java
  31. 371 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderController.java
  32. 124 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderRefundController.java
  33. 86 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserTenantAlbumRecordController.java
  34. 122 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/VideoLessonController.java
  35. 61 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/VipCardRecordController.java
  36. 110 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/coupon/CouponInfoController.java
  37. 49 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/ActivityEvaluationRecordController.java
  38. 216 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenClient.java
  39. 53 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/UserPaymentClient.java
  40. 137 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/ActivityVo.java
  41. 131 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/CouponInfoVO.java
  42. 90 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/LiveRoomVO.java
  43. 82 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/task/TaskController.java
  44. 232 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/vo/UserPaymentOrderVo.java

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

@@ -0,0 +1,115 @@
+package com.yonge.cooleshow.student.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.CourseHomeworkSubmitDto;
+import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
+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.CourseHomeworkDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseHomeworkVo;
+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.util.ArrayList;
+import java.util.List;
+
+/**
+ * Description 学生课后作业相关接口
+ *
+ * @author liujunchi
+ * @date 2022-04-13
+ */
+@Api(tags = "学生课后作业相关接口")
+@RestController
+@RequestMapping("${app-config.url.student:}/homework")
+public class CourseHomeworkController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+
+    @Autowired
+    private CourseHomeworkService courseHomeworkService;
+
+
+    @ApiOperation(value = "首页-我的课程-课程详情(陪练课)-课后作业信息详情",notes = "传入课程编号ID")
+    @GetMapping(value = "/detail/{courseId}")
+    public HttpResponseResult<CourseHomeworkDetailVo> detail(@ApiParam(value = "课程编号ID", required = true)
+                                                                 @PathVariable("courseId") Long courseId) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(courseId,sysUser);
+        if (info != null) return info;
+        return succeed(courseHomeworkService.getCourseHomeworkDetailByCourseId(courseId, sysUser.getId()));
+    }
+
+    private HttpResponseResult checkCourseSchedule(Long courseId,SysUser sysUser) {
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+        if (!courseScheduleService.checkStudentCourseSchedule(sysUser.getId(), courseId)) {
+            return failed("学生只能看自己购买的课程详情");
+        }
+        return null;
+    }
+
+
+    @ApiOperation(value = "陪练课-作业提交", httpMethod = "POST", consumes = "application/json", produces = "application/json")
+    @PostMapping(value = "/submit", consumes = "application/json", produces = "application/json")
+    public HttpResponseResult<Boolean> reviewCourseHomework(@Valid @RequestBody CourseHomeworkSubmitDto submitDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        HttpResponseResult info = checkCourseSchedule(submitDto.getCourseScheduleId(),sysUser);
+        if (info != null) return info;
+        submitDto.setStudentId(sysUser.getId());
+        return succeed(courseHomeworkService.submitCourseHomework(submitDto));
+    }
+
+    @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.getSubmit() == null) {
+            return failed("提交状态不能为空");
+        }
+        query.setDecorate(YesOrNoEnum.YES);
+        query.setStudentId(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(String.valueOf(item.getTeacherId()));
+            }
+        }
+
+        return succeed(PageUtil.pageInfo(page));
+    }
+
+
+}

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

@@ -0,0 +1,103 @@
+package com.yonge.cooleshow.student.controller;
+
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+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.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.annotation.Resource;
+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.student:}/imGroup")
+public class ImGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private ImGroupService imGroupService;
+    @Resource
+    private SysUserService sysUserService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation("获取群详情")
+    @PostMapping(value = "/getDetail/{groupId}")
+    public HttpResponseResult<ImGroup> getDetail(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+
+        // 获取用户ID
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        ImGroup group = imGroupService.findGroupInfoById(groupId, sysUser.getId());
+        // 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.STUDENT);
+        return succeed(imGroupService.queryAll(imGroupSearchDto));
+    }
+
+    @ApiOperation("获取指定用户的群列表")
+    @PostMapping(value = "/queryTeacherGroup")
+    public HttpResponseResult<List<ImGroupResultDto>> queryTeacherGroup(@RequestBody ImGroupSearchDto imGroupSearchDto) throws Exception {
+
+        // 群类型
+        if (StringUtils.isEmpty(imGroupSearchDto.getType())) {
+            imGroupSearchDto.setType("FAN");
+        }
+        // 用户群身份
+        imGroupSearchDto.setRoleType(ImGroupMemberRoleType.STUDENT);
+
+        return succeed(imGroupService.queryTeacherFun(imGroupSearchDto));
+    }
+
+    @ApiOperation("退出群聊")
+    @PostMapping(value = "/quit/{groupId}")
+    public HttpResponseResult quit(@ApiParam(value = "群编号", required = true) @PathVariable("groupId") String groupId) throws Exception {
+        imGroupService.quit(groupId,sysUserService.getUserId(), ClientEnum.STUDENT);
+        return succeed();
+    }
+}
+

+ 47 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupMemberAuditController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.student.controller;
+
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.ImGroupMemberAudit;
+import com.yonge.cooleshow.biz.dal.enums.ImGroupMemberRoleType;
+import com.yonge.cooleshow.biz.dal.service.ImGroupMemberAuditService;
+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.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.annotation.Resource;
+import javax.validation.Valid;
+
+/**
+ * (ImGroupMemberAudit)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 17:18:51
+ */
+@Api(tags = "入群申请")
+@RestController
+@RequestMapping("${app-config.url.student:}/imGroupMemberAudit")
+public class ImGroupMemberAuditController extends BaseController {
+
+    @Resource
+    private ImGroupMemberAuditService imGroupMemberAuditService;
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation("申请入群")
+    @PostMapping(value = "/apply")
+    public HttpResponseResult apply(@Valid @RequestBody ImGroupMemberAudit imGroupMemberAudit) throws Exception {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        imGroupMemberAudit.setRoleType(ImGroupMemberRoleType.STUDENT);
+        imGroupMemberAudit.setUserId(sysUser.getId());
+        imGroupMemberAuditService.apply(imGroupMemberAudit, false);
+        return succeed();
+    }
+}
+

+ 93 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupMemberController.java

@@ -0,0 +1,93 @@
+package com.yonge.cooleshow.student.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.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.annotation.Resource;
+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.student:}/imGroupMember")
+public class ImGroupMemberController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private ImGroupMemberService imGroupMemberService;
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "groupId", dataType = "Long", 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.getBaseMapper().selectList(Wrappers.<ImGroupMember>query().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);
+    }
+}
+

+ 46 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/ImGroupNoticeController.java

@@ -0,0 +1,46 @@
+package com.yonge.cooleshow.student.controller;
+
+
+import com.yonge.cooleshow.biz.dal.dto.ImGroupNoticeDto;
+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 io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+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.annotation.Resource;
+import java.util.Map;
+
+/**
+ * 群公告(ImGroupNotice)表控制层
+ *
+ * @author zx
+ * @since 2022-03-22 10:45:58
+ */
+@Api(tags = "群公告")
+@RestController
+@RequestMapping("${app-config.url.student:}/imGroupNotice")
+public class ImGroupNoticeController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private ImGroupNoticeService imGroupNoticeService;
+
+    @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/student/controller/ImUserFriendController.java

@@ -0,0 +1,102 @@
+package com.yonge.cooleshow.student.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.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.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.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.annotation.Resource;
+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.student:}/imUserFriend")
+public class ImUserFriendController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private ImUserFriendService imUserFriendService;
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "search", dataType = "String", value = "根据用户编号、昵称模糊查询")
+    })
+    @ApiOperation("获取通讯录成员列表")
+    @PostMapping(value = "/queryAll")
+    public HttpResponseResult<List<ImUserWrapper.ImUserFriend>> queryAll(@RequestBody Map<String,Object> params) throws Exception {
+
+        // 用户ID
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (Objects.isNull(sysUser)) {
+            return failed("请登录");
+        }
+
+        // 学生好友列表
+        List<ImUserWrapper.ImUserFriend> userFriends = imUserFriendService.findUserAllImFriendInfo(ClientEnum.STUDENT, sysUser.getId(), params);
+
+        /*Object search = params.get("search");
+        List<ImUserFriend> userFriends = imUserFriendService.getBaseMapper().selectList(Wrappers.<ImUserFriend>query().lambda()
+                .and(Objects.nonNull(search) && StringUtils.isNotEmpty(search.toString()),
+                        e->e.eq(ImUserFriend::getFriendId, search).or()
+                        .like(ImUserFriend::getFriendNickname, search))
+                .eq(ImUserFriend::getUserId,sysUser.getId()).orderByDesc(ImUserFriend::getId));
+
+        for (ImUserFriend item : userFriends) {
+            // 学生目前添加好友都为老师
+            item.clientType(ClientEnum.TEACHER)
+                    .setImFriendId(MessageFormat.format("{0}", String.valueOf(item.getFriendId())));
+        }*/
+
+        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.STUDENT);
+        if (Objects.isNull(userFriend)) {
+            return failed("当前好友不存在");
+        }
+
+        if (Objects.isNull(userFriend.getFriendType())) {
+            userFriend.setFriendType(ClientEnum.TEACHER);
+        }
+
+        return succeed(ImUserFriendVO.ImUserFriend.from(JSON.toJSONString(userFriend)));
+    }
+}
+

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

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.student.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.student:}/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);
+	}
+}

+ 206 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicAlbumController.java

@@ -0,0 +1,206 @@
+package com.yonge.cooleshow.student.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.Student;
+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.StudentService;
+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.student:}/music/album")
+@Api(tags = "专辑表 API接口")
+public class MusicAlbumController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+	@Autowired
+	private MusicAlbumService musicAlbumService;
+    @Autowired
+    private StudentService studentService;
+    @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("用户信息获取失败");
+        }
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            return failed("用户信息获取失败");
+        }
+        
+        if(query.getSubjectIdList() == null || query.getSubjectIdList().size() == 0){
+        	List<Long> subjectIdList = new ArrayList<Long>();
+        	if(StringUtils.isNotBlank(student.getSubjectId())){
+        		String[] subjectIds = student.getSubjectId().split(",");
+        		for(String s : subjectIds){
+                	subjectIdList.add(Long.parseLong(s));
+        		}
+        		query.setSubjectIdList(subjectIdList);
+        	}
+        }
+
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+
+        // query.setSubjectIds(student.getSubjectId());
+        query.setAlbumStatus(YesOrNoEnum.YES);
+        query.setSortBy(1);
+        query.setUserId(sysUser.getId());
+        IPage<MusicAlbumVo> iPage = musicAlbumService.selectStudentPage(PageUtil.getPage(query),query, ClientEnum.STUDENT);
+        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.STUDENT);
+        AlbumDetailVo albumDetailVo = musicAlbumService.detail(PageUtil.getPage(query), query,sysUser,ClientEnum.STUDENT);
+        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.STUDENT);
+        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 = "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(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.STUDENT);
+        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.STUDENT);
+
+        IPage<MusicAlbumVo> albumVoIPage = musicAlbumService.favoriteAlbum(PageUtil.getPage(query), search, ClientEnum.STUDENT);
+        return succeed(PageUtil.pageInfo(albumVoIPage));
+    }
+}

+ 405 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java

@@ -0,0 +1,405 @@
+package com.yonge.cooleshow.student.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.AppMusicSheetVo;
+import com.yonge.cooleshow.biz.dal.dto.MusicSheetRenderDto;
+import com.yonge.cooleshow.biz.dal.dto.search.MusicAlbumSearch;
+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.Student;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+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.MusicAlbumService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.vo.AlbumAndSheetVo;
+import com.yonge.cooleshow.biz.dal.vo.CheckVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetDetailVo;
+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.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 com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
+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.Date;
+import java.util.Optional;
+
+/**
+ * 曲谱表 web 控制层
+ * @author yzp
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.student:}/music/sheet")
+@Api(tags = "曲谱表 API接口")
+public class MusicSheetController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+	@Autowired
+	private MusicSheetService musicSheetService;
+
+    @Autowired
+    private MusicAlbumService musicAlbumService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    @Autowired
+    private StudentService studentService;
+
+
+    /**
+     * 查询单条
+     */
+    @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) {
+            sysUser = null;
+        }
+        return succeed(musicSheetService.detail(id, sysUser, ClientEnum.STUDENT));
+    }
+
+    @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()) {
+            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 {
+
+            Student student = studentService.getById(sysUser.getId());
+            if (student == null) {
+                return failed("用户信息获取失败");
+            }
+            if(StringUtils.isBlank(query.getSubjectIds())){
+            	query.setSubjectIds(student.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.STUDENT);
+        return succeed(PageUtil.pageInfo(musicSheetVoIPage));
+    }
+
+    @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="/albumAndSheetList", consumes="application/json", produces="application/json")
+    public HttpResponseResult<AlbumAndSheetVo> albumAndSheetList(@RequestBody StudentMusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            return failed("用户信息获取失败");
+        }
+
+        // 检查app版本
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(query.getPlatform(), query.getVersion());
+        // 学生 只能看通过审核 并且 启用的 曲目
+        query.setState(YesOrNoEnum.YES);
+        query.setAuditVersion(appAuditVersion);
+        query.setAuditStatus(AuthStatusEnum.PASS);
+        query.setStudentId(sysUser.getId());
+
+        // query.setSubjectIds(student.getSubjectId());
+        query.setRows(query.getSheetRow());
+        IPage<MusicSheetVo> musicSheetVoIPage = musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.STUDENT);
+
+        MusicAlbumSearch musicAlbumSearch = new MusicAlbumSearch();
+        musicAlbumSearch.setAlbumStatus(YesOrNoEnum.YES);
+        musicAlbumSearch.setSortBy(1);
+        musicAlbumSearch.setIdAndName(query.getIdAndName());
+        musicAlbumSearch.setAuditVersion(appAuditVersion);
+        musicAlbumSearch.setAlbumTagIds(query.getMusicTagIds());
+        musicAlbumSearch.setPage(query.getPage());
+        // musicAlbumSearch.setSubjectIds(student.getSubjectId());
+        musicAlbumSearch.setRows(query.getAlbumRow());
+        IPage<MusicAlbumVo> musicAlbumVoIPage = musicAlbumService.selectPage(PageUtil.getPage(musicAlbumSearch), musicAlbumSearch);
+
+        AlbumAndSheetVo albumAndSheetVo = new AlbumAndSheetVo();
+        albumAndSheetVo.setMusicSheetList(PageUtil.pageInfo(musicSheetVoIPage));
+        albumAndSheetVo.setMusicAlbumList(PageUtil.pageInfo(musicAlbumVoIPage));
+        return succeed(albumAndSheetVo);
+    }
+
+    /**
+     * 曲目收藏
+     */
+    @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 = "gift", value = "课程赠品 0:购买 1:赠品, 默认值: 0"),
+            @ApiImplicitParam(name = "page", value = "分页查询, 默认值: 1"),
+            @ApiImplicitParam(name = "row", value = "当前页行数, 默认值: 10"),
+    })
+    @GetMapping("/my")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> myMusic(@RequestParam(value = "gift", required = false, defaultValue = "0") Integer gift,
+                                                              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);
+        search.setUserType(ClientEnum.STUDENT);
+        search.setPurchaseType(Optional.ofNullable(search.getPurchaseType()).orElse(PurchaseRecordTypeEnum.MUSIC));
+        search.setCourseGift(gift);
+
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.myMusic(PageUtil.getPage(query),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.STUDENT);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+
+    /**
+     * 最近练习
+     */
+    @GetMapping("/practice")
+    @ApiOperation(value = "最近练习")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> practiceMusic(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.practiceMusic(PageUtil.getPage(query),search);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
+
+
+
+    /**
+     * 最近练习
+     */
+    @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));
+    }
+
+    /**
+     * 检查实名认证
+     */
+    @GetMapping("/realNameAuth/check")
+    @ApiOperation(value = "检查实名认证")
+    public HttpResponseResult<CheckVo> realNameAuthCheck() {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        CheckVo checkVo = new CheckVo();
+        if (StringUtil.isEmpty(sysUser.getIdCardNo())) {
+            checkVo.setCheck(YesOrNoEnum.NO);
+        }  else {
+            checkVo.setCheck(YesOrNoEnum.YES);
+        }
+        return succeed(checkVo);
+    }
+
+
+    /**
+     * 实名认证
+     */
+    @PostMapping(value = "/realNameAuth" ,consumes="application/json", produces="application/json")
+    @ApiOperation(value = "实名认证", httpMethod="POST",consumes="application/json", produces="application/json")
+    public HttpResponseResult<IdcardInfoExtractor> realNameAuth(@Valid @RequestBody RealnameAuthReq realNameAuthDto) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        return sysUserFeignService.realNameAuth(realNameAuthDto);
+    }
+
+    @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("用户信息获取失败");
+        }
+
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            return failed("用户信息获取失败");
+        }
+        if(StringUtils.isBlank(query.getSubjectIds())){
+            query.setSubjectIds(student.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.STUDENT).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);
+    }
+}

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

@@ -0,0 +1,34 @@
+package com.yonge.cooleshow.student.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.student:}/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);
+	}
+
+}

+ 50 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/PaymentController.java

@@ -0,0 +1,50 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.result.BaseResult;
+import com.yonge.toolset.payment.base.enums.OpenEnum;
+import com.yonge.toolset.payment.base.model.OpenAuth;
+import com.yonge.toolset.payment.core.props.PaymentProperties;
+import com.yonge.toolset.payment.core.service.PaymentClient;
+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.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Map;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/3/11 18:16
+ */
+@RestController
+@RequestMapping("${app-config.url.student:}/payment")
+@Api(value = "付款接口", tags = "付款接口")
+public class PaymentController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private PaymentClient paymentClient;
+    @Autowired
+    private PaymentProperties paymentProperties;
+
+    @ApiOperation(value = "通过用户给的授权码获取三方支付授权信息")
+    @GetMapping("/getOpenId")
+    public HttpResponseResult<Map<String, Object>> getOpenId(OpenAuth openAuth) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        OpenEnum openType = OpenEnum.valueOf(paymentProperties.getOpenType());
+        openAuth.setOpenType(openType);
+        BaseResult<Map<String, Object>> res = paymentClient.getOpenAuthMsg(openAuth);
+        return HttpResponseResult.status(res);
+    }
+}

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

@@ -0,0 +1,88 @@
+package com.yonge.cooleshow.student.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.student:}/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.STUDENT);
+        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);
+    }
+}

+ 148 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentActivityController.java

@@ -0,0 +1,148 @@
+package com.yonge.cooleshow.student.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.EvaluationRecordDto;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.queryInfo.UserRewardQueryInfo;
+import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
+import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
+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.student.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.student:}/activity")
+public class StudentActivityController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(StudentActivityController.class);
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+
+    @Autowired
+    private ActivityEvaluationRecordService activityEvaluationRecordService;
+
+    @Autowired
+    private ActivityUserRewardService activityUserRewardService;
+
+    @ApiOperation(value = "评测活动参与项目", notes = "评测项目id")
+    @PostMapping(value = "/evaluation/{evaluationId}")
+    public HttpResponseResult<Boolean> joinEvaluation(@PathVariable Long evaluationId) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(activityPlanService.joinEvaluation(evaluationId, user));
+    }
+
+
+    @ApiOperation(value = "免费活动报名活动报名", notes = "活动id")
+    @PostMapping(value = "/joinActivity/{id}")
+    public HttpResponseResult<Boolean> joinActivity(@PathVariable Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        return succeed(activityPlanService.joinActivity(id, user));
+    }
+
+
+    @ApiOperation(value = "保存活动分数")
+    @PostMapping("/evaluationScore")
+    public HttpResponseResult evaluationScore( @RequestBody EvaluationRecordDto record){
+
+        // 判断是否为活动评测 活动评测 记录活动记录
+        if (record.getEvaluationId() != null) {
+            try {
+                activityEvaluationRecordService.saveRecord(record.getEvaluationId(),record.getUserId(),record.getScore());
+            } catch (Exception e) {
+                e.printStackTrace();
+                log.error("活动评测记录保存失败,{}",e.fillInStackTrace());
+            }
+        }
+        return succeed();
+    }
+
+
+    @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.STUDENT);
+        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.STUDENT);
+        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));
+    }
+}
+

+ 172 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java

@@ -0,0 +1,172 @@
+package com.yonge.cooleshow.student.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.search.QueryMyFollowSearch;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.SmsCodeService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+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.toolset.base.page.PageInfo;
+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.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.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.student:}/student")
+@Api(value = "学生表", tags = "学生表")
+public class StudentController extends BaseController {
+    @Autowired
+    private StudentService studentService;
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private SmsCodeService smsCodeService;
+
+
+    @ApiOperation(value = "查询指定学员信息")
+    @GetMapping("/queryUserById")
+    public HttpResponseResult<com.yonge.cooleshow.biz.dal.vo.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));
+    }
+
+    @ApiOperation(value = "查询学员")
+    @GetMapping("/queryUser")
+    public HttpResponseResult<Student> queryUser() {
+        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));
+    }
+
+    @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.STUDENT);
+        return succeed(idcardInfoExtractor);
+    }
+
+    @PostMapping("/logoffAccount")
+    @ApiOperation(value = "注销学生账户")
+    public HttpResponseResult<Boolean> logoffAccount(@RequestParam("code") String code) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        if (StringUtils.isEmpty(code)) {
+            return failed("验证码不能为空");
+        }
+        boolean validCode = smsCodeService.verifyValidCode(user.getPhone(), code, "");
+        if (validCode) {
+            return failed("验证码错误");
+        }
+
+        studentService.lambdaUpdate()
+                .set(Student::getLockFlag, true)
+                .set(Student::getHideFlag, true)
+                .eq(Student::getUserId, user.getId())
+                .update();
+        user.setDelFlag(true);
+        sysUserFeignService.update(user);
+        return succeed();
+    }
+
+}

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

@@ -0,0 +1,100 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+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.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+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.student:}/courseGroup")
+public class StudentCourseGroupController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private CourseGroupService courseGroupService;
+
+    @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(已完成)"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "subjectId", dataType = "Integer", value = "声部id"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", 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) {
+        param.put("os","student");
+        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);
+        return succeed(courseGroupService.queryPageLiveCourseGroup(param));
+    }
+
+    @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("/liveSubject")
+    public HttpResponseResult<List<Subject>> liveSubject() {
+        List<Subject> subjectList = courseGroupService.liveSubject();
+        return succeed(subjectList);
+    }
+}
+

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

@@ -0,0 +1,194 @@
+package com.yonge.cooleshow.student.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.AppAuditVersionSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
+import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleReplied;
+import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.CourseRepliedService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
+import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoClassVo;
+import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomePage;
+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.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 javax.validation.constraints.NotNull;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/13
+ */
+@Api(tags = "学生课表")
+@RestController
+@RequestMapping("${app-config.url.student:}/courseSchedule")
+public class StudentCourseScheduleController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private CourseScheduleService courseScheduleService;
+    @Autowired
+    private CourseRepliedService repliedService;
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    @ApiOperation("学生端-查询房间配置")
+    @GetMapping("/selectRoomConfig")
+    public HttpResponseResult<Object> selectRoomConfig() {
+        return succeed(courseScheduleService.selectRoomConfig());
+    }
+
+    @ApiOperation("学生端-我的-我的课程-陪练课")
+    @PostMapping("/queryStudentPracticeCourse")
+    public HttpResponseResult<PageInfo<MyCourseVo>> queryStudentPracticeCourse(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        search.setStudentId(user.getId());
+        IPage<MyCourseVo> pages = courseScheduleService.queryStudentPracticeCourse(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @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<CourseScheduleReplied> selectReplied(@Validated @RequestBody CourseScheduleReplied replied) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        replied.setStudentId(user.getId());
+        replied.setCourseGroupType(CourseScheduleEnum.PRACTICE.getCode());
+        return succeed(repliedService.selectReplied(replied));
+    }
+
+    @ApiOperation("学生端-课表-日历")
+    @PostMapping("/queryCourseScheduleStudent")
+    public HttpResponseResult<Set<String>> queryCourseScheduleStudent(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        search.setStudentId(user.getId());
+        return succeed(courseScheduleService.queryCourseScheduleStudent(search));
+    }
+
+    @ApiOperation(value = "学生端-首页-陪练课老师列表", notes = "search:{\"subjectId\":null,\"search\":\"\",\"sort\":\"starGrade ASC,expTime DESC,subjectPrice DESC\"}")
+    @PostMapping("/teacherList")
+    public HttpResponseResult<PageInfo<PracticeTeacherVo>> teacherList(@RequestBody PracticeTeacherSearch search) {
+        IPage<PracticeTeacherVo> pages = courseScheduleService.teacherList(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "学生端-课表-日历-用户", notes = "search:{\"classDate\":\"2022-03-27\"}")
+    @PostMapping("/queryCourseTeacher")
+    public HttpResponseResult<Map<String, Object>> queryCourseTeacher(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        search.setStudentId(user.getId());
+        return succeed(courseScheduleService.queryCourseTeacher(search));
+    }
+
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "studentId", dataType = "String", required = true, value = "学生id"),
+            @ApiImplicitParam(name = "classDate", dataType = "String", required = true, value = "年月"),
+            @ApiImplicitParam(name = "courseState", dataType = "String", value = "课程状态 NOT_START未开始 ING进行中 COMPLETE已完成 CANCEL已取消"),
+            @ApiImplicitParam(name = "subjectId", dataType = "Long", value = "声部id"),
+            @ApiImplicitParam(name = "page", dataType = "Integer", value = "页数"),
+            @ApiImplicitParam(name = "rows", dataType = "Integer", value = "每页数量"),
+    })
+    @ApiOperation("学生-查询直播课")
+    @PostMapping("/queryStudentLiveCourse")
+    public HttpResponseResult<PageInfo<CourseStudent>> queryStudentLiveCourse(@RequestBody Map<String, Object> param) {
+        return succeed(courseScheduleService.queryStudentLiveCourse(param));
+    }
+
+    @ApiOperation("学生-首页-直播课&视频课&最近课程")
+    @GetMapping("/queryLiveAndVideo")
+    public HttpResponseResult<StudentHomePage> queryLiveAndVideo(AppAuditVersionSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        // 检查app版本审核/正式
+        YesOrNoEnum appAuditVersion = appVersionInfoService.getAppAuditVersion(search.getPlatform(),
+                                                                               search.getVersion());
+        return succeed(courseScheduleService.queryLiveAndVideo(user.getId(),null,appAuditVersion));
+    }
+
+    @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("查询老师陪练课配置")
+    @GetMapping("/getTeacherSubjectPrice")
+    public HttpResponseResult<List<TeacherSubjectPrice>> getTeacherSubjectPrice(@NotNull Long teacherId) {
+        return succeed(courseScheduleService.teacherSubjectPrice(teacherId));
+    }
+
+    @ApiOperation("学生端-我的课程-琴房课列表")
+    @PostMapping("/queryPianoClass")
+    public HttpResponseResult<PageInfo<PianoClassVo>> queryPianoClass(@RequestBody MyCourseSearch search) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+
+        search.setStudentId(user.getId());
+        IPage<PianoClassVo> pages = courseScheduleService.queryPianoClass(PageUtil.getPage(search), search);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}
+

+ 92 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomController.java

@@ -0,0 +1,92 @@
+package com.yonge.cooleshow.student.controller;
+
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.biz.dal.entity.ImUserStateSync;
+import com.yonge.cooleshow.biz.dal.entity.RoomInfoCache;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherLivingInfoVo;
+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.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 javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 直播房间与课程的关系表表(LiveRoom)表控制层
+ *
+ * @author hgw
+ * @since 2022-03-18 15:41:16
+ */
+@Api(tags = "直播房间与课程的关系表表")
+@RestController
+@RequestMapping("${app-config.url.student:}/liveRoom")
+public class StudentLiveRoomController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(StudentLiveRoomController.class);
+    /**
+     * 服务对象
+     */
+    @Resource
+    private LiveRoomService liveRoomService;
+    
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    
+    @Autowired
+    private StudentService studentService;
+
+    /**
+     * 校验房间信息,及个人信息
+     *
+     * @param roomUid 房间uid
+     */
+    @GetMapping("/studentCheckRoomInfo")
+    public HttpResponseResult<RoomInfoCache> studentCheckRoomInfo(@RequestParam("roomUid") String roomUid) {
+        return succeed(liveRoomService.studentCheckRoomInfo(roomUid));
+    }
+
+    @ApiOperation("观看者-进入房间")
+    @GetMapping(value = "/joinRoom")
+    public HttpResponseResult<RoomInfoCache> joinRoom(String roomUid, Long userId) {
+        return succeed(liveRoomService.joinRoom(roomUid, userId));
+    }
+
+    /**
+     * 同步融云用户状态变更
+     *
+     * @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);
+    }
+
+    @ApiOperation("老师直播列表")
+    @GetMapping("/queryTeacherLivingList")
+    public HttpResponseResult<List<TeacherLivingInfoVo>> queryTeacherLivingList() {
+
+        return succeed(liveRoomService.queryTeacherLivingList());
+    }
+
+}
+

+ 45 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/StudentLiveRoomVideoController.java

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

+ 59 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SubjectController.java

@@ -0,0 +1,59 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+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.SubjectService;
+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.student:}/subject")
+@Api(tags = "声部服务")
+@RestController
+public class SubjectController extends BaseController {
+    @Autowired
+    private SubjectService subjectService;
+    
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    
+    @Autowired
+    private StudentService studentService;
+
+    @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) {
+        	Student student = studentService.getById(sysUser.getId());
+        	if(student != null){
+        		userExtSubjectIds = student.getSubjectId();
+        	}
+        }
+        List<Subject> subjectSelect = subjectService.subjectSelect(type, userExtSubjectIds);
+        return succeed(subjectSelect);
+    }
+
+}

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

@@ -0,0 +1,82 @@
+package com.yonge.cooleshow.student.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.student:}/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/student/controller/SysImComplaintController.java

@@ -0,0 +1,47 @@
+package com.yonge.cooleshow.student.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.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.annotation.Resource;
+import java.util.Date;
+
+/**
+ * (SysImComplaint)表控制层
+ *
+ * @author zx
+ * @since 2022-06-13 16:37:00
+ */
+@RestController
+@Api(tags = "消息(群组)投诉")
+@RequestMapping("${app-config.url.student:}/sysImComplaint")
+public class SysImComplaintController extends BaseController {
+    /**
+     * 服务对象
+     */
+    @Resource
+    private SysImComplaintService sysImComplaintService;
+    @Resource
+    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/student/controller/SysMessageController.java

@@ -0,0 +1,131 @@
+package com.yonge.cooleshow.student.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.student:}/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("STUDENT");
+		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,"STUDENT") > 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(), "STUDENT");
+
+		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, "STUDENT");
+		return succeed();
+	}
+}

+ 83 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysMusicCompareRecordController.java

@@ -0,0 +1,83 @@
+package com.yonge.cooleshow.student.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.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.student:}/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("student");
+        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());
+        if (StringUtils.isEmpty(queryInfo.getStartTime())) {
+            return failed("时间不能为空");
+        }
+        queryInfo.setClientId("student");
+        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));
+    }
+
+}

+ 53 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysSuggestionController.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.SysSuggestion;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+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.student:}")
+public class SysSuggestionController extends BaseController {
+
+    @Autowired
+    private SysSuggestionService sysSuggestionService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @ApiOperation(value = "新增")
+    @RequestMapping("sysSuggestion/add")
+    public Object add(SysSuggestion sysSuggestion) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null) {
+            return failed("用户信息获取失败");
+        }
+        sysSuggestion.setUserId(sysUser.getId());
+        sysSuggestion.setClientType("STUDENT");
+        if(StringUtils.isEmpty(sysSuggestion.getMobileNo())){
+            sysSuggestion.setMobileNo(sysUser.getPhone());
+        }
+        // 查询学生是否是机构学生 机构学生设置来源为机构
+        Student student = studentService.getById(sysUser.getId());
+        if (student.getTenantId() !=null && student.getTenantId() != -1) {
+            sysSuggestion.setClientType(ClientEnum.TENANT_STUDENT.getCode());
+        }
+
+        sysSuggestionService.insert(sysSuggestion);
+        return succeed();
+    }
+
+}

+ 84 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/SysUserContractRecordController.java

@@ -0,0 +1,84 @@
+package com.yonge.cooleshow.student.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;
+
+import javax.annotation.Resource;
+
+/**
+ * 用户协议记录表-一个用户一种协议一个版本一条记录(SysUserContractRecord)表控制层
+ *
+ * @author hgw
+ * @since 2022-05-07 15:04:05
+ */
+@Api(tags = "用户协议记录表-一个用户一种协议一个版本一条记录")
+@RestController
+@RequestMapping("${app-config.url.student:}/sysUserContractRecord")
+public class SysUserContractRecordController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private ContractTemplateService contractTemplateService;
+    @Resource
+    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.STUDENT, 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 = "/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.STUDENT, user);
+    }
+
+    @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.STUDENT, contractType);
+    }
+}
+

+ 146 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TeacherController.java

@@ -0,0 +1,146 @@
+package com.yonge.cooleshow.student.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.TeacherStyleSearch;
+import com.yonge.cooleshow.biz.dal.entity.TeacherStyleVideo;
+import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.StudentStarService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.TeacherStyleVideoService;
+import com.yonge.cooleshow.biz.dal.vo.HotTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherHomeVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherStyleVideoVo;
+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.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.CollectionUtils;
+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.stream.Collectors;
+
+@RestController
+@RequestMapping("${app-config.url.student:}/teacher")
+@Api(value = "教师表", tags = "教师表")
+public class TeacherController extends BaseController {
+    @Autowired
+    private TeacherStyleVideoService styleVideoService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private TeacherService teacherService;
+    @Autowired
+    private StudentStarService studentStarService;
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+    
+    @Autowired
+    private StudentService studentService;
+
+    @ApiOperation(value = "老师风采-分页")
+    @PostMapping("/stylePage")
+    public HttpResponseResult<PageInfo<TeacherStyleVideoVo>> stylePage(@RequestBody TeacherStyleSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        /*if(StringUtils.isBlank(query.getSubjectId())){
+        	Student student = studentService.getById(user.getId());
+        	query.setSubjectId(student.getSubjectId());
+        }*/
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(), query.getVersion()));
+        query.setStudentId(user.getId());
+        IPage<TeacherStyleVideoVo> pages = styleVideoService.stylePage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "查询教师基本信息")
+    @GetMapping("/queryTeacherHome")
+    public HttpResponseResult<TeacherHomeVo> queryTeacherHome(@ApiParam(value = "老师ID", required = true) @RequestParam("userId") Long userId) {
+        if (null == userId) {
+            return failed("缺少老师ID");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        HttpResponseResult<TeacherHomeVo> res = teacherService.queryTeacherHome(user.getId(), userId);
+        //学生端过滤只看审核通过的
+        if (null != res.getData() && !CollectionUtils.isEmpty(res.getData().getStyleVideo())) {
+            List<TeacherStyleVideo> styleVideo = res.getData().getStyleVideo();
+            List<TeacherStyleVideo> collect = styleVideo.stream().filter(o -> AuthStatusEnum.PASS.equals(o.getAuthStatus())).collect(Collectors.toList());
+            res.getData().setStyleVideo(collect);
+        }
+        return res;
+    }
+
+    @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);
+    }
+
+    @ApiOperation(value = "增加视频浏览量")
+    @GetMapping("/addVideoBrowse")
+    public HttpResponseResult<Boolean> addVideoBrowse(@ApiParam(value = "视频ID", required = true) @RequestParam("videoId") Long videoId) {
+        if (null == videoId) {
+            return failed("缺少videoId");
+        }
+        return styleVideoService.addVideoBrowse(videoId);
+    }
+
+    @ApiOperation(value = "增加主页浏览量")
+    @GetMapping("/addHomeBrowse")
+    public HttpResponseResult<Boolean> addHomeBrowse(@ApiParam(value = "老师ID", required = true) @RequestParam("userId") Long userId) {
+        if (null == userId) {
+            return failed("缺少userId");
+        }
+        return teacherService.addHomeBrowse(userId);
+    }
+
+    @ApiOperation(value = "推荐老师列表")
+    @GetMapping("/queryHotTeacherList")
+    public HttpResponseResult<List<HotTeacherVo>> queryHotTeacherList() {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        Long userId = null;
+        if (user != null && null != user.getId()) {
+            userId = user.getId();
+        }
+        List<HotTeacherVo> list = teacherService.queryHotTeacherList(userId);
+        
+        for(HotTeacherVo vo : list){
+        	vo.setGraduateSchool(null);
+        }
+        
+        return HttpResponseResult.succeed(list);
+    }
+}

+ 80 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantActivationCodeController.java

@@ -0,0 +1,80 @@
+package com.yonge.cooleshow.student.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.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.Student;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.TenantActivationCodeService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantActivationCodeWrapper;
+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 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.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/tenantActivationCode")
+@Api(tags = "机构激活码")
+public class TenantActivationCodeController extends BaseController {
+
+    @Autowired
+    private TenantActivationCodeService tenantActivationCodeService;
+
+    @Resource
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @ApiOperation(value = "查询分页", notes = "机构激活码- 传入 TenantActivationCodeVo.TenantActivationCodeQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantActivationCodeWrapper.TenantActivationCode>> page(
+            @RequestBody TenantActivationCodeWrapper.TenantActivationCodeQuery query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || null == sysUser.getId()) {
+            throw new BizException("请登录");
+        }
+        Student student = studentService.getById(sysUser.getId());
+        if (student == null) {
+            throw new BizException("学生不存在");
+        }
+        query.setActivationPhone(sysUser.getPhone());
+        query.setTenantId(student.getTenantId());
+        // 查询数据
+        IPage<TenantActivationCodeWrapper.TenantActivationCode> pages =
+                tenantActivationCodeService.selectPage(QueryInfo.getPage(query), query);
+        for (TenantActivationCodeWrapper.TenantActivationCode record : pages.getRecords()) {
+            String activationCode = record.getActivationCode();
+            String substring = activationCode.substring(3);
+            record.setActivationCode("***" + substring);
+        }
+        return succeed(QueryInfo.pageInfo(pages, pages.getRecords()));
+    }
+
+    @ApiOperation(value = "激活激活码")
+    @PostMapping("/active")
+    public HttpResponseResult<Boolean> active(@RequestParam("activationCode") String activationCode) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null || null == sysUser.getId()) {
+            throw new BizException("请登录");
+        }
+        tenantActivationCodeService.active(activationCode, sysUser.getId());
+        return succeed();
+    }
+}

+ 89 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumController.java

@@ -0,0 +1,89 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.service.TenantAlbumRefService;
+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.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.security.access.prepost.PreAuthorize;
+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;
+
+/**
+ * @Author:haonan
+ * @Date:2023/7/27 18:26
+ * @Filename:TenantAlbumController
+ */
+
+@RestController
+@RequestMapping("${app-config.url.student:}/StudentTenantAlbum")
+@Api(value = "学生端机构管理", tags = "学生端机构管理")
+public class TenantAlbumController {
+    @Autowired
+    TenantAlbumService tenantAlbumService;
+
+    @Autowired
+    private TenantAlbumMusicService tenantAlbumMusicService;
+
+    @Autowired
+    private TenantAlbumRefService tenantAlbumRefService;
+
+    @Autowired
+    private TenantInfoService tenantInfoService;
+
+    /**
+     * 查询分页
+     *
+     * @param query
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "StudentTenantAlbum")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/page')")
+    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> page(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+    /**
+     * 下拉框搜索
+     *
+     * @param query
+     */
+    @PostMapping("/select")
+    @ApiOperation(value = "查询分页", notes = "StudentTenantAlbum")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/select')")
+    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> select(@RequestBody TenantAlbumWrapper.TenantAlbumQuery query) {
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = tenantAlbumService.selectPage(QueryInfo.getPage(query), query);
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+
+
+    /**
+     * 查询详情
+     *
+     * @param id 详情ID
+     * @return TenantAlbum
+     */
+    @PostMapping("/detail")
+    @ApiOperation(value = "查询详情", notes = "detail")
+    @PreAuthorize("@pcs.hasPermissions('tenantAlbum/detail')")
+    public HttpResponseResult<TenantAlbumWrapper.TenantAlbum> detail(@RequestParam("id") Long id) {
+
+        return null;
+    }
+
+
+
+}

+ 68 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/TenantAlbumSheetController.java

@@ -0,0 +1,68 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+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.service.TenantAlbumMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumMusicWrapper;
+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.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
+ * @date 2022-03-26 00:21:46
+ * @version v1.0
+ **/
+@RestController
+@RequestMapping("${app-config.url.student:}/tenantAlbumMusic")
+@Api(tags = "机构专辑曲目 API接口")
+public class TenantAlbumSheetController extends BaseController {
+
+    @Autowired
+    private TenantAlbumMusicService tenantAlbumMusicService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @ApiOperation(value = "查询条件")
+    @PostMapping("/selectCondition")
+    public HttpResponseResult<TenantAlbumMusicWrapper.TenantAlbumMusicSelectData> selectCondition(@RequestBody TenantAlbumMusicWrapper.TenantAlbumMusicSelect query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        /*if(StringUtils.isBlank(query.getSubjectId())){
+        	Student student = studentService.getById(user.getId());
+        	query.setSubjectId(student.getSubjectId());
+        }*/
+        return succeed(tenantAlbumMusicService.getTenantAlbumMusicQuery(query));
+    }
+
+
+
+    @ApiOperation(value = "分页查询")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantAlbumMusicWrapper.StudentTenantAlbumMusic>> page(@RequestBody TenantAlbumMusicWrapper.StudentTenantAlbumMusicQuery query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        IPage<TenantAlbumMusicWrapper.StudentTenantAlbumMusic> page = tenantAlbumMusicService.selectPage(QueryInfo.getPage(query), query);
+        return succeed((PageUtil.pageInfo(page)));
+    }
+
+
+}

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

@@ -0,0 +1,80 @@
+package com.yonge.cooleshow.student.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.student:}")
+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));
+    }
+}

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

@@ -0,0 +1,371 @@
+package com.yonge.cooleshow.student.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.enums.GoodTypeEnum;
+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.student.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.student:}/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 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.STUDENT);
+        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.STUDENT);
+        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 = "通过业务id查询用户正在交易中的订单")
+    @PostMapping("/getPendingOrder")
+    @ApiImplicitParams({
+            @ApiImplicitParam(
+                    name = "goodType",
+                    value = "订单类型:  PRACTICE、陪练课购买  LIVE、直播课购买 VIDEO、视频课购买 MUSIC、单曲点播 ACTI_REGIST、活动报名",
+                    paramType = "query", dataType = "String", required = true
+            ),
+            @ApiImplicitParam(
+                    name = "bizId",
+                    value = "业务id 直播课、陪练课购买为课程组id;陪练课为老师id;单曲点播传曲子id",
+                    paramType = "query", dataType = "Long"
+            )
+    })
+    public HttpResponseResult<UserOrderVo> getPendingOrder(@ApiIgnore @RequestBody OrderSearch query) {
+        if (null == query.getGoodType()
+                || (!GoodTypeEnum.VIP.getCode().equals(query.getGoodType()) && null == query.getBizId())) {
+            return HttpResponseResult.failed("参数异常");
+        }
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        return userOrderService.getPendingOrder(query);
+    }
+
+    @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.STUDENT.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);
+    }
+
+
+    @Autowired
+    private TenantStaffService tenantStaffService;
+
+    @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.STUDENT.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.STUDENT.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.STUDENT.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.STUDENT);
+
+        // 用户取消支付
+
+
+        return HttpResponseResult.succeed(userPaymentCoreService.orderPayType(payTypeReq));
+    }
+
+
+}

+ 124 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserOrderRefundController.java

@@ -0,0 +1,124 @@
+package com.yonge.cooleshow.student.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.OrderRefundReq;
+import com.yonge.cooleshow.biz.dal.dto.search.UserOrderRefundSearch;
+import com.yonge.cooleshow.biz.dal.service.UserOrderRefundService;
+import com.yonge.cooleshow.biz.dal.service.UserPaymentCoreService;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderRefundVo;
+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.mybatis.support.PageUtil;
+import com.yonge.toolset.payment.util.DistributedLock;
+import io.swagger.annotations.Api;
+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.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.concurrent.TimeUnit;
+
+@RestController
+@RequestMapping("${app-config.url.student:}/userOrderRefunds")
+@Api(value = "用户退款表", tags = "用户退款表")
+public class UserOrderRefundController extends BaseController {
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private RedissonClient redissonClient;
+    @Autowired
+    private UserOrderRefundService userOrderRefundService;
+
+    @Autowired
+    private UserPaymentCoreService userPaymentCoreService;
+
+    /**
+     * 查询单条
+     */
+    @GetMapping("/detail/{id}")
+    @ApiOperation(value = "详情", notes = "传入id")
+    public HttpResponseResult<UserOrderRefundVo> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(userOrderRefundService.detail(id));
+    }
+
+    /**
+     * 查询分页
+     */
+    @PostMapping("/page")
+    @ApiOperation(value = "查询分页", notes = "传入orderRefundsSearch")
+    public HttpResponseResult<PageInfo<UserOrderRefundVo>> page(@RequestBody UserOrderRefundSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        IPage<UserOrderRefundVo> pages = userOrderRefundService.selectPage(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "订单退款")
+    @PostMapping("/orderRefund")
+    public HttpResponseResult<Boolean> orderRefund(@RequestBody OrderRefundReq refundReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        refundReq.setUserId(user.getId());
+
+        try {
+            HttpResponseResult<Boolean> res = DistributedLock.of(redissonClient)
+                    .runIfLockToFunction(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(refundReq.getOrderNo())
+                            , userOrderRefundService::orderRefund, refundReq, 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("/orderRefund/v2")
+    public HttpResponseResult<Boolean> orderRefundV2(@RequestBody OrderRefundReq refundReq) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        refundReq.setUserId(user.getId());
+
+        try {
+            DistributedLock.of(redissonClient)
+                    .runIfLockCanGet(CacheNameEnum.LOCK_EXECUTE_ORDER.getRedisKey(refundReq.getUserId())
+                            , () -> {
+                        userPaymentCoreService.refundPayment(refundReq.getOrderNo(),refundReq.getReason());
+                            }, 10L,TimeUnit.SECONDS);
+            return HttpResponseResult.succeed();
+        } catch (BizException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("订单退款失败");
+        }
+    }
+}

+ 86 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserTenantAlbumRecordController.java

@@ -0,0 +1,86 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.entity.UserTenantAlbumRecord;
+import com.yonge.cooleshow.biz.dal.service.UserTenantAlbumRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.TenantAlbumWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserTenantAlbumRecordWrapper;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.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.student:}/userTenantAlbumRecord")
+@Api(tags = "购买训练工具记录")
+public class UserTenantAlbumRecordController {
+
+    @Autowired
+    private UserTenantAlbumRecordService userTenantAlbumRecordService;
+
+    @ApiOperation(value = "详情", notes = "购买训练工具记录-根据详情ID查询单条, 传入id")
+    @PreAuthorize("@auditsvc.hasPermissions('userTenantAlbumRecord/detail', {'BACKEND'})")
+    //@GetMapping("/detail/{id}")
+    public R<UserTenantAlbumRecord> detail(@PathVariable("id") Long id) {
+
+        UserTenantAlbumRecord wrapper = userTenantAlbumRecordService.detail(id);
+
+        return R.from(wrapper);
+    }
+
+    @ApiOperation(value = "查询分页", notes = "购买训练工具记录- 传入 UserTenantAlbumRecordWrapper.UserTenantAlbumRecordQuery")
+    //@PreAuthorize("@auditsvc.hasPermissions('userTenantAlbumRecord/page', {'BACKEND'})")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<TenantAlbumWrapper.TenantAlbum>> page(@RequestBody UserTenantAlbumRecordWrapper.UserTenantAlbumRecordQuery query) {
+
+        IPage<TenantAlbumWrapper.TenantAlbum> pages = userTenantAlbumRecordService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "新增", notes = "购买训练工具记录- 传入 UserTenantAlbumRecordWrapper.UserTenantAlbumRecord")
+    @PreAuthorize("@auditsvc.hasPermissions('userTenantAlbumRecord/save', {'BACKEND'})")
+    //@PostMapping("/save")
+    public R<JSONObject> add(@Validated @RequestBody UserTenantAlbumRecord userTenantAlbumRecord) {
+
+        // 新增数据
+        userTenantAlbumRecordService.save(userTenantAlbumRecord);
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "修改", notes = "购买训练工具记录- 传入 UserTenantAlbumRecordWrapper.UserTenantAlbumRecord")
+    @PreAuthorize("@auditsvc.hasPermissions('userTenantAlbumRecord/update', {'BACKEND'})")
+    //@PostMapping("/update")
+    public R<JSONObject> update(@Validated @RequestBody UserTenantAlbumRecord userTenantAlbumRecord) {
+
+        // 更新数据
+        userTenantAlbumRecordService.updateById(userTenantAlbumRecord);
+
+        return R.defaultR();
+    }
+
+    @ApiOperation(value = "删除", notes = "购买训练工具记录- 传入id")
+    @PreAuthorize("@auditsvc.hasPermissions('userTenantAlbumRecord/remove', {'BACKEND'})")
+    //@PostMapping("/remove")
+    public R<Boolean> remove(@RequestParam Long id) {
+
+        return R.from(userTenantAlbumRecordService.removeById(id));
+    }
+}

+ 122 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/VideoLessonController.java

@@ -0,0 +1,122 @@
+package com.yonge.cooleshow.student.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.VideoLessonEvaluateSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonGroupSearch;
+import com.yonge.cooleshow.biz.dal.entity.VideoLessonEvaluate;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonEvaluateService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupDetailService;
+import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupService;
+import com.yonge.cooleshow.biz.dal.vo.LessonGroupVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonEvaluateVo;
+import com.yonge.cooleshow.biz.dal.vo.VideoLessonStudentVo;
+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.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 javax.validation.constraints.NotNull;
+
+/**
+ * @Author: cy
+ * @Date: 2022/4/2
+ */
+@RestController
+@RequestMapping("${app-config.url.student:}/videoLesson")
+@Api(tags = "视频课")
+@Validated
+public class VideoLessonController extends BaseController {
+    @Autowired
+    private VideoLessonGroupDetailService detailService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private VideoLessonEvaluateService evaluateService;
+    @Autowired
+    private VideoLessonGroupService videoLessonGroupService;
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+    /**
+     * @Description: 根据组id查询视频课
+     * @Author: cy
+     * @Date: 2022/4/2
+     */
+    @ApiOperation(value = "根据组id查询视频课")
+    @GetMapping(value = "/selectVideoLesson")
+    public HttpResponseResult<VideoLessonStudentVo> selectVideoLesson(@NotNull(message = "视频组id不能为空") Long groupId) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        return succeed(detailService.selectVideoLesson(groupId,user.getId()));
+    }
+
+    /**
+     * @Description: 视频课评价
+     * @Author: cy
+     * @Date: 2022/4/11
+     */
+    @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));
+    }
+
+    /**
+     * @Description: 查询视频课组
+     * @Author: cy
+     * @Date: 2022/4/11
+     */
+    @ApiOperation(value = "查询视频课组")
+    @PostMapping(value = "/selectGroup")
+    public HttpResponseResult<PageInfo<LessonGroupVo>> page(@RequestBody VideoLessonGroupSearch query) {
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+        IPage<LessonGroupVo> pages = videoLessonGroupService.selectLessonGroup(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "学生端-我的-我的课程-购买的视频课组")
+    @PostMapping("/selectMyGroup")
+    public HttpResponseResult<PageInfo<LessonGroupVo>> myLessonGroup(@RequestBody VideoLessonGroupSearch query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setStudentId(user.getId());
+        IPage<LessonGroupVo> pages = videoLessonGroupService.selectLessonGroupById(PageUtil.getPage(query), query);
+        return succeed(PageUtil.pageInfo(pages));
+    }
+}

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

@@ -0,0 +1,61 @@
+package com.yonge.cooleshow.student.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.student:}/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));
+    }
+}

+ 110 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/coupon/CouponInfoController.java

@@ -0,0 +1,110 @@
+package com.yonge.cooleshow.student.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.student.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.student:}/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.STUDENT.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.STUDENT)
+                        .build().couponType(couponType));
+
+        return succeed(JSON.parseArray(JSON.toJSONString(wrappers), CouponInfoVO.CouponStateStat.class));
+    }
+}

+ 49 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/ActivityEvaluationRecordController.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.student.controller.open;
+
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import io.swagger.annotations.Api;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@RestController
+@RequestMapping("${app-config.url.student:}/open/activityEvaluationRecord")
+@Api(value = "评测活动表", tags = "评测活动表")
+public class ActivityEvaluationRecordController extends BaseController {
+
+    @Autowired
+    private ActivityEvaluationRecordService activityEvaluationRecordService;
+	@Resource
+	private SysUserFeignService sysUserFeignService;
+
+    /**
+     * 查询活动排行榜
+     */
+    @GetMapping("/queryRankingList")
+	public HttpResponseResult<ModelMap> queryRankingList(Long activityPlanId, Long activityEvaluationId, int limit) {
+
+        ModelMap model = new ModelMap();
+        
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user != null && null != user.getId()) {
+            ActivityRankingVo userActivityRankingVo = activityEvaluationRecordService.queryUserRanking(activityPlanId, activityEvaluationId, user.getId());
+            model.put("userActivityRankingVo", userActivityRankingVo);
+        }
+        
+    	List<ActivityRankingVo> rankingList =  activityEvaluationRecordService.queryRankingList(activityPlanId, activityEvaluationId, limit);
+    	model.put("rankingList", rankingList);
+    	
+        return succeed(model);
+	}
+
+}

+ 216 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenClient.java

@@ -0,0 +1,216 @@
+package com.yonge.cooleshow.student.controller.open;
+
+import com.microsvc.toolkit.middleware.oss.wrapper.OssWrapper;
+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.MemberPriceSettingsSearch;
+import com.yonge.cooleshow.biz.dal.entity.SysConfig;
+import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
+import com.yonge.cooleshow.biz.dal.service.AppVersionInfoService;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.service.MemberPriceSettingsService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.UploadFileService;
+import com.yonge.cooleshow.biz.dal.vo.CheckVo;
+import com.yonge.cooleshow.biz.dal.vo.MemberPriceVo;
+import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
+import com.yonge.cooleshow.biz.dal.wrapper.liveroom.LiveRoomWrapper;
+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.student.io.request.LiveRoomVO;
+import com.yonge.toolset.base.util.StringUtil;
+import com.yonge.toolset.thirdparty.entity.UploadSign;
+import com.yonge.toolset.utils.string.ValueUtil;
+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.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+
+@RestController
+@RequestMapping("${app-config.url.student:}/open")
+@Api(value = "开放权限接口", tags = "开放权限接口")
+public class OpenClient extends BaseController {
+    @Autowired
+    private TeacherService teacherService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private SysConfigService sysConfigService;
+    @Autowired
+    private UploadFileService uploadFileService;
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private MemberPriceSettingsService memberPriceSettingsService;
+
+    @Autowired
+    private ActivityPlanService activityPlanService;
+    @Autowired
+    private LiveRoomService liveRoomService;
+
+    @Autowired
+    private AppVersionInfoService appVersionInfoService;
+
+    @ApiOperation(value = "查询老师头像昵称信息")
+    @GetMapping("/getTeacher")
+    public HttpResponseResult<TeacherVo> getTeacher(@ApiParam(value = "老师ID", required = true) @RequestParam("userId") Long userId) {
+        if (null == userId) {
+            return failed("缺少老师ID");
+        }
+        TeacherVo detail = teacherService.detail(userId);
+        detail.setIdCardNo(ValueUtil.fuzzyIdCard(detail.getIdCardNo()));
+        detail.setPhone(ValueUtil.fuzzyMobile(detail.getPhone()));
+        return HttpResponseResult.succeed(detail);
+    }
+
+    @ApiOperation(value = "绑定老师")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "phone", value = "手机号", required = true, dataType = "String"),
+            @ApiImplicitParam(name = "userId", value = "老师id", required = true),
+            @ApiImplicitParam(name = "isUpdate", value = "是否更新绑定老师", dataType = "Boolean")
+    })
+    @GetMapping("/bindTeacher")
+    public HttpResponseResult<Map<String,TeacherVo>> bindTeacher(String phone, Long userId, Boolean isUpdate) {
+        if (StringUtil.isEmpty(phone)) {
+            return failed("缺少手机号");
+        }
+        if (null == userId) {
+            return failed("缺少老师ID");
+        }
+        return studentService.bindTeacher(phone, userId, isUpdate);
+    }
+
+
+
+    @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, user);
+
+        return succeed(activityVo);
+    }
+
+
+
+    @ApiOperation(value = "新增曲谱渲染图")
+    @PostMapping(value="/music/sheet/img")
+    public HttpResponseResult<Boolean> img(@RequestBody @Valid MusicImgDto musicImgDto) {
+        return succeed(musicSheetService.updateMusicImg(musicImgDto, musicImgDto.getMusicSheetId()));
+    }
+
+
+    @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));
+    }
+
+    @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/list")
+    @ApiOperation(value = "查询列表")
+    public HttpResponseResult<MemberPriceVo> list(@RequestBody MemberPriceSettingsSearch query) {
+        MemberPriceVo memberPriceVo = memberPriceSettingsService.getVipShare(query);
+        return succeed(memberPriceVo);
+    }
+
+
+    @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 = "直播间详情信息", notes = "直播间ID")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "分享用户ID", dataType = "Long")
+    })
+    @GetMapping("/liveRoom/detail/{ID}")
+    public HttpResponseResult<LiveRoomVO> liveRoomDetailInfo(@PathVariable("ID") String liveRoomId,
+                                                             @RequestParam(value = "userId", required = false) Long userId) {
+
+        if (StringUtils.isEmpty(liveRoomId)) {
+            return failed("无效的直播间编号");
+        }
+
+        LiveRoomWrapper roomWrapper = liveRoomService.findLiveRoomDetailInfoByRoomId(liveRoomId, userId);
+        if (Objects.isNull(roomWrapper)) {
+            return failed("无效的直播间编号");
+        }
+
+        return succeed(LiveRoomVO.from(roomWrapper.jsonString()));
+    }
+
+
+    @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/student/controller/open/UserPaymentClient.java

@@ -0,0 +1,53 @@
+package com.yonge.cooleshow.student.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.student.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.student:}/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);
+    }
+
+}

+ 137 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/ActivityVo.java

@@ -0,0 +1,137 @@
+package com.yonge.cooleshow.student.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是 0:否")
+        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;
+        }
+    }
+}

+ 131 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/CouponInfoVO.java

@@ -0,0 +1,131 @@
+package com.yonge.cooleshow.student.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(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("可用品类 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;
+
+    }
+}

+ 90 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/io/request/LiveRoomVO.java

@@ -0,0 +1,90 @@
+package com.yonge.cooleshow.student.io.request;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * Created by Eric.Shang on 2022/9/22.
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LiveRoomVO implements Serializable {
+
+    @ApiModelProperty(value = "课程组id")
+    private Long courseGroupId;
+
+    @ApiModelProperty(value = "课程id")
+    private Long courseId;
+
+    @ApiModelProperty(value = "主讲人id/老师id")
+    private Long speakerId;
+
+    @ApiModelProperty(value = "房间编号")
+    private String roomUid;
+
+    @ApiModelProperty(value = "房间标题/最多12个字")
+    private String roomTitle;
+
+    @ApiModelProperty(value = "直播开始时间")
+    @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+    private Date liveStartTime;
+
+    @ApiModelProperty(value = "直播结束时间")
+    @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+    private Date liveEndTime;
+
+    @ApiModelProperty(value = "直播内容/最多200个字")
+    private String liveRemark;
+
+    @ApiModelProperty(value = "直播状态 0未开始 1已开始 2已结束")
+    private Integer liveState;
+
+    @ApiModelProperty(value = "房间状态 0正常 1已删除 2已销毁")
+    private Integer roomState;
+
+    @ApiModelProperty(value = "房间类型 live直播课  temp临时直播间")
+    private String type;
+
+    @ApiModelProperty(value = "封面图片")
+    private String coverPic;
+
+    @ApiModelProperty(value = "直播老师信息")
+    private UserInfo teacher;
+
+    @ApiModelProperty(value = "分享同学信息")
+    private UserInfo student;
+
+    public static LiveRoomVO from(String jsonString) {
+        return JSON.parseObject(jsonString, LiveRoomVO.class);
+    }
+
+    /**
+     * 直播间老师信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class UserInfo implements Serializable {
+
+        @ApiModelProperty("用户名")
+        private String username;
+
+        @ApiModelProperty("手机号")
+        private String phone;
+
+        @ApiModelProperty("头像")
+        private String avatar;
+
+        @ApiModelProperty("真实姓名")
+        private String realName;
+    }
+}

+ 82 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/task/TaskController.java

@@ -0,0 +1,82 @@
+package com.yonge.cooleshow.student.task;
+
+import com.yonge.cooleshow.biz.dal.entity.StudentTotal;
+import com.yonge.cooleshow.biz.dal.service.CourseRepliedService;
+import com.yonge.cooleshow.biz.dal.service.StudentTimeService;
+import com.yonge.cooleshow.biz.dal.service.StudentTotalService;
+import com.yonge.cooleshow.biz.dal.service.VipCardRecordService;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+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("${app-config.url.student:}/task")
+@ApiIgnore
+public class TaskController extends BaseController {
+    @Autowired
+    private StudentTotalService studentTotalService;
+    @Autowired
+    private StudentTimeService studentTimeService;
+    @Autowired
+    private VipCardRecordService vipCardRecordService;
+    @Autowired
+    private CourseRepliedService repliedService;
+    /***
+     * 查询所有学生统计数据
+     * @author liweifan
+     * @updateTime 2022/4/29 19:12
+     * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.util.List<com.yonge.cooleshow.biz.dal.entity.StudentTotal>>
+     */
+    @GetMapping("/queryStudentTotal")
+    public HttpResponseResult<List<StudentTotal>> queryStudentTotal() {
+        return succeed(studentTotalService.queryStudentTotal());
+    }
+
+    /***
+     * 半小时一次
+     * @author liweifan
+     * @updateTime 2022/4/29 19:12
+     * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.lang.Boolean>
+     */
+    @GetMapping("/halfHourTask")
+    public HttpResponseResult<Boolean> halfHourTask() {
+        //会员卡到期提醒
+        vipCardRecordService.pollExpireMsg();
+        return succeed(true);
+    }
+
+    /***
+     * 统计学员第一次购买时间
+     *
+     * @author liweifan
+     * @updateTime 2022/4/29 19:12
+     * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.lang.Boolean>
+     */
+    @GetMapping("/studentFirstBuy")
+    public HttpResponseResult<Boolean> studentFirstBuy() {
+        //统计学员第一次购买时间
+        studentTimeService.totalStudentTime();
+        return succeed(true);
+    }
+
+    /**
+     * @Description: 当日陪练课未对老师评价(每晚9点,已评价不发)
+     * @Author: cy
+     * @Date: 2022/5/6
+     */
+    @GetMapping("/noRepliedTeacher")
+    public HttpResponseResult noRepliedTeacher() {
+        repliedService.noRepliedTeacher();
+        return succeed();
+    }
+}

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

@@ -0,0 +1,232 @@
+package com.yonge.cooleshow.student.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);
+        }
+    }
+}