liujc 1 rok pred
rodič
commit
2e9ab38122
32 zmenil súbory, kde vykonal 2075 pridanie a 4 odobranie
  1. 109 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicController.java
  2. 90 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicStarController.java
  3. 79 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenUserMusicController.java
  4. 46 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenUserMusicStarController.java
  5. 106 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserMusicController.java
  6. 79 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserMusicStarController.java
  7. 75 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenUserMusicController.java
  8. 39 0
      cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenUserMusicStarController.java
  9. 5 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/constant/SysConfigConstant.java
  10. 31 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EUserMusicType.java
  11. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareRecordDao.java
  12. 90 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusic.java
  13. 44 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusicStar.java
  14. 28 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/UserMusicMapper.java
  15. 28 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/UserMusicStarMapper.java
  16. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/StudentService.java
  17. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SubjectService.java
  18. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/SysMusicCompareRecordService.java
  19. 3 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/TeacherService.java
  20. 66 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserMusicService.java
  21. 63 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserMusicStarService.java
  22. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/StudentServiceImpl.java
  23. 17 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SubjectServiceImpl.java
  24. 23 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMusicCompareRecordServiceImpl.java
  25. 15 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherServiceImpl.java
  26. 329 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicServiceImpl.java
  27. 236 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserMusicStarServiceImpl.java
  28. 135 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicStarWrapper.java
  29. 223 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicWrapper.java
  30. 7 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  31. 46 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicMapper.xml
  32. 42 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicStarMapper.xml

+ 109 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicController.java

@@ -0,0 +1,109 @@
+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.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+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.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+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 lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/userMusic")
+@Api(tags = "用户曲目作品")
+public class UserMusicController {
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @ApiOperation(value = "详情", notes = "用户曲目作品-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<UserMusicWrapper.UserMusic> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().id(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build,
+            JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.STUDENT.name()).build());
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            throw new BizException(999,"作品已删除");
+        }
+
+        return HttpResponseResult.succeed(records.get(0));
+    }
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        query.setClientType(ClientEnum.STUDENT);
+        JwtUserInfo<Object> userInfo = JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.STUDENT.name()).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(query), query, userInfo);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "保存草稿/发布作品", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusic")
+    @PostMapping("/save")
+    public HttpResponseResult<JSONObject> add(@Validated @RequestBody UserMusicWrapper.AddUserMusic userMusic) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        userMusic.setUserId(user.getId());
+        userMusic.setClientType(ClientEnum.STUDENT);
+        // 新增数据
+        userMusicService.save(userMusic);
+
+        return HttpResponseResult.succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "用户曲目作品- 传入id")
+    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam String id) {
+
+        if (StringUtils.isBlank(id)) {
+            throw new BizException( "id不能为空");
+        }
+        List<String> list = Arrays.asList(id.split(","));
+
+        userMusicService.lambdaUpdate()
+            .in(UserMusic::getId, list)
+            .set(UserMusic::getDelFlag, true)
+            .update();
+
+        return HttpResponseResult.succeed(true);
+    }
+}

+ 90 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/UserMusicStarController.java

@@ -0,0 +1,90 @@
+package com.yonge.cooleshow.student.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.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.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SubjectService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicStarService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.util.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/userMusicStar")
+@Api(tags = "用户曲目作品点赞记录")
+public class UserMusicStarController {
+
+    @Autowired
+    private UserMusicStarService userMusicStarService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品点赞记录- 传入 UserMusicStarWrapper.UserMusicStarQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicStarWrapper.UserMusicStar>> page(@RequestBody @Validated UserMusicStarWrapper.UserMusicStarQuery query) {
+
+        IPage<UserMusicStarWrapper.UserMusicStar> pages = userMusicStarService.selectPage(QueryInfo.getPage(query), query);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+
+    @ApiOperation(value = "点赞/取消点赞")
+    @PostMapping("/star")
+    public HttpResponseResult<JSONObject> star(@Validated @RequestBody UserMusicStarWrapper.Star star) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        star.setUserId(user.getId());
+        star.setClientType(ClientEnum.STUDENT);
+        // 新增数据
+        userMusicStarService.star(star);
+
+        return HttpResponseResult.succeed();
+    }
+}

+ 79 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/student/controller/open/OpenUserMusicController.java

@@ -0,0 +1,79 @@
+package com.yonge.cooleshow.student.controller.open;
+
+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.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import springfox.documentation.annotations.ApiIgnore;
+
+import java.util.List;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/open/userMusic")
+@Api(tags = "用户曲目作品")
+public class OpenUserMusicController {
+
+    @Autowired
+    private UserMusicService userMusicService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+
+    @ApiOperation(value = "详情", notes = "用户曲目作品-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<UserMusicWrapper.UserMusic> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        JwtUserInfo userInfo = null;
+        if (user != null && null != user.getId()) {
+            userInfo = JwtUserInfo.builder()
+                .clientType(ClientEnum.STUDENT.name())
+                .userId(user.getId().toString())
+                .build();
+        }
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().id(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build
+            ,userInfo);
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            throw new BizException(999,"作品已删除");
+        }
+
+        return HttpResponseResult.succeed(records.get(0));
+    }
+
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        JwtUserInfo userInfo = null;
+        if (user != null && null != user.getId()) {
+            userInfo = JwtUserInfo.builder()
+                .clientType(ClientEnum.STUDENT.name())
+                .userId(user.getId().toString())
+                .build();
+        }
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(query), query
+            ,userInfo);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+}

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

@@ -0,0 +1,46 @@
+package com.yonge.cooleshow.student.controller.open;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicStarService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.student:}/open/userMusicStar")
+@Api(tags = "用户曲目作品点赞记录")
+public class OpenUserMusicStarController {
+
+    @Autowired
+    private UserMusicStarService userMusicStarService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品点赞记录- 传入 UserMusicStarWrapper.UserMusicStarQuery")
+    @PostMapping("/page")
+    public R<PageInfo<UserMusicStarWrapper.UserMusicStar>> page(@RequestBody @Validated UserMusicStarWrapper.UserMusicStarQuery query) {
+
+        IPage<UserMusicStarWrapper.UserMusicStar> pages = userMusicStarService.selectPage(QueryInfo.getPage(query), query);
+
+        return R.from(QueryInfo.pageInfo(pages));
+    }
+}

+ 106 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/UserMusicController.java

@@ -0,0 +1,106 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.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.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+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 lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userMusic")
+@Api(tags = "用户曲目作品")
+public class UserMusicController {
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @ApiOperation(value = "详情", notes = "用户曲目作品-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<UserMusicWrapper.UserMusic> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().id(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build,
+            JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.TEACHER.name()).build());
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            throw new BizException(999,"作品已删除");
+        }
+
+        return HttpResponseResult.succeed(records.get(0));
+    }
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        query.setUserId(user.getId());
+        query.setClientType(ClientEnum.TEACHER);
+        JwtUserInfo<Object> userInfo = JwtUserInfo.builder().userId(user.getId().toString()).clientType(ClientEnum.TEACHER.name()).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(query), query, userInfo);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+    @ApiOperation(value = "保存草稿/发布作品", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusic")
+    @PostMapping("/save")
+    public HttpResponseResult<JSONObject> add(@Validated @RequestBody UserMusicWrapper.AddUserMusic userMusic) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        userMusic.setUserId(user.getId());
+        userMusic.setClientType(ClientEnum.TEACHER);
+        // 新增数据
+        userMusicService.save(userMusic);
+
+        return HttpResponseResult.succeed();
+    }
+
+    @ApiOperation(value = "删除", notes = "用户曲目作品- 传入id")
+    @PostMapping("/remove")
+    public HttpResponseResult<Boolean> remove(@RequestParam String id) {
+
+        if (StringUtils.isBlank(id)) {
+            throw new BizException( "id不能为空");
+        }
+        List<String> list = Arrays.asList(id.split(","));
+
+        userMusicService.lambdaUpdate()
+            .in(UserMusic::getId, list)
+            .set(UserMusic::getDelFlag, true)
+            .update();
+
+        return HttpResponseResult.succeed(true);
+    }
+}

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

@@ -0,0 +1,79 @@
+package com.yonge.cooleshow.teacher.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.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.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.util.StringUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import static com.yonge.cooleshow.common.entity.HttpResponseResult.failed;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/userMusicStar")
+@Api(tags = "用户曲目作品点赞记录")
+public class UserMusicStarController {
+
+    @Autowired
+    private UserMusicStarService userMusicStarService;
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品点赞记录- 传入 UserMusicStarWrapper.UserMusicStarQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicStarWrapper.UserMusicStar>> page(@RequestBody @Validated UserMusicStarWrapper.UserMusicStarQuery query) {
+
+        IPage<UserMusicStarWrapper.UserMusicStar> pages = userMusicStarService.selectPage(QueryInfo.getPage(query), query);
+
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+
+
+    @ApiOperation(value = "点赞/取消点赞")
+    @PostMapping("/star")
+    public HttpResponseResult<JSONObject> star(@Validated @RequestBody UserMusicStarWrapper.Star star) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        star.setUserId(user.getId());
+        star.setClientType(ClientEnum.TEACHER);
+        // 新增数据
+        userMusicStarService.star(star);
+
+        return HttpResponseResult.succeed();
+    }
+}

+ 75 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenUserMusicController.java

@@ -0,0 +1,75 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+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.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.UserMusicService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/userMusic")
+@Api(tags = "用户曲目作品")
+public class OpenUserMusicController {
+
+    @Autowired
+    private UserMusicService userMusicService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+
+
+    @ApiOperation(value = "详情", notes = "用户曲目作品-根据详情ID查询单条, 传入id")
+    @GetMapping("/detail/{id}")
+    public HttpResponseResult<UserMusicWrapper.UserMusic> detail(@PathVariable("id") Long id) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        JwtUserInfo userInfo = null;
+        if (user != null && null != user.getId()) {
+            userInfo = JwtUserInfo.builder()
+                .clientType(ClientEnum.TEACHER.name())
+                .userId(user.getId().toString())
+                .build();
+        }
+        UserMusicWrapper.UserMusicQuery build = UserMusicWrapper.UserMusicQuery.builder().id(id).build();
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(build), build
+            ,userInfo);
+        List<UserMusicWrapper.UserMusic> records = pages.getRecords();
+        if (records.isEmpty()) {
+            throw new BizException(999,"作品已删除");
+        }
+
+        return HttpResponseResult.succeed(records.get(0));
+    }
+
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品- 传入 UserMusicWrapper.UserMusicQuery")
+    @PostMapping("/page")
+    public HttpResponseResult<PageInfo<UserMusicWrapper.UserMusic>> page(@RequestBody UserMusicWrapper.UserMusicQuery query) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        JwtUserInfo userInfo = null;
+        if (user != null && null != user.getId()) {
+            userInfo = JwtUserInfo.builder()
+                .clientType(ClientEnum.TEACHER.name())
+                .userId(user.getId().toString())
+                .build();
+        }
+        IPage<UserMusicWrapper.UserMusic> pages = userMusicService.selectPage(QueryInfo.getPage(query), query
+            ,userInfo);
+
+        return HttpResponseResult.succeed(QueryInfo.pageInfo(pages));
+    }
+}

+ 39 - 0
cooleshow-app/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenUserMusicStarController.java

@@ -0,0 +1,39 @@
+package com.yonge.cooleshow.teacher.controller.open;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.microsvc.toolkit.common.response.paging.PageInfo;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import com.microsvc.toolkit.common.response.template.R;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.service.UserMusicStarService;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("${app-config.url.teacher:}/open/userMusicStar")
+@Api(tags = "用户曲目作品点赞记录")
+public class OpenUserMusicStarController {
+
+    @Autowired
+    private UserMusicStarService userMusicStarService;
+
+    @ApiOperation(value = "查询分页", notes = "用户曲目作品点赞记录- 传入 UserMusicStarWrapper.UserMusicStarQuery")
+    @PostMapping("/page")
+    public R<PageInfo<UserMusicStarWrapper.UserMusicStar>> page(@RequestBody @Validated UserMusicStarWrapper.UserMusicStarQuery query) {
+
+        IPage<UserMusicStarWrapper.UserMusicStar> pages = userMusicStarService.selectPage(QueryInfo.getPage(query), query);
+
+        return R.from(QueryInfo.pageInfo(pages));
+    }
+}

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

@@ -413,4 +413,9 @@ public interface SysConfigConstant {
      * 添加合作信息的短信发送手机号
      */
     String ADD_COOPERATE_TENANT_SEND_MSG_PHONE = "add_cooperate_tenant_send_msg_phone";
+
+    /**
+     * 我的作品默认视频封面图
+     */
+    String USER_MUSIC_VIDEO_DEFAULT_URL = "user_music_video_default_url";
 }

+ 31 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/enums/EUserMusicType.java

@@ -0,0 +1,31 @@
+package com.yonge.cooleshow.common.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Getter;
+
+/**
+ * 客户端类型
+ * Created by Eric.Shang on 2022/11/4.
+ */
+@Getter
+public enum EUserMusicType implements BaseEnum<String,EUserMusicType> {
+
+    // 草稿 作品
+    DRAFT("草稿 作品"),
+    // 正式 作品
+    FORMAL("正式 作品"),
+    ;
+
+    private final String msg;
+
+    @EnumValue
+    private final String code;
+
+    EUserMusicType(String msg) {
+        this.msg = msg;
+
+        this.code = this.name();
+    }
+
+}

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

@@ -66,4 +66,6 @@ public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareR
 	//统计用户指定周训练数据
 	SysMusicCompareWeekData getUserWeekCompareData(@Param("userId") Long userId,
 												   @Param("monday") String monday);
+
+    List<SysMusicCompareRecord> selectByIds(@Param("musicPracticeRecordIds") List<Long> musicPracticeRecordIds);
 }

+ 90 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusic.java

@@ -0,0 +1,90 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.common.enums.EUserMusicType;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 用户曲目作品
+ * 2023-09-05 15:27:10
+ */
+@Data
+@ApiModel(" UserMusic-用户曲目作品")
+@TableName("user_music")
+public class UserMusic implements Serializable {
+
+    @TableId(value = "id_",type = IdType.AUTO)
+	    private Long id;
+
+    @ApiModelProperty("用户ID")
+	@TableField(value = "user_id_")
+    private Long userId;
+
+    @ApiModelProperty("用户类型")
+	@TableField(value = "client_type_")
+    private ClientEnum clientType;
+
+    @ApiModelProperty("关联练习数据ID")
+	@TableField(value = "music_practice_record_id_")
+    private Long musicPracticeRecordId;
+
+    @ApiModelProperty("曲目ID")
+	@TableField(value = "music_sheet_id_")
+    private Long musicSheetId;
+
+
+    @ApiModelProperty("原伴奏")
+    @TableField(value = "accompany_url_")
+    private String accompanyUrl;
+
+    @ApiModelProperty("草稿 作品")
+	@TableField(value = "type_")
+    private EUserMusicType type;
+
+    @ApiModelProperty("封面图")
+	@TableField(value = "img_")
+    private String img;
+
+
+    @ApiModelProperty("视频封面图")
+    @TableField(value = "video_img_")
+    private String videoImg;
+
+
+    @ApiModelProperty("发布描述")
+    @TableField(value = "desc_")
+    private String desc;
+
+    @ApiModelProperty("视频地址")
+	@TableField(value = "video_url_")
+    private String videoUrl;
+
+    @ApiModelProperty("json配置")
+	@TableField(value = "json_config_")
+    private String jsonConfig;
+
+    @ApiModelProperty("点赞数")
+    @TableField(value = "like_num_")
+    private Integer likeNum;
+
+    @ApiModelProperty("删除标记")
+	@TableField(value = "del_flag_")
+    private Boolean delFlag;
+
+    @TableField(value = "submit_time_")
+    private Date submitTime;
+
+	@TableField(value = "create_time_")
+    private Date createTime;
+
+}

+ 44 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserMusicStar.java

@@ -0,0 +1,44 @@
+package com.yonge.cooleshow.biz.dal.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 用户曲目作品点赞记录
+ * 2023-10-30 14:59:53
+ */
+@Data
+@ApiModel(" UserMusicStar-用户曲目作品点赞记录")
+@TableName("user_music_star")
+public class UserMusicStar implements Serializable {
+
+	    @TableId(value = "id_",type = IdType.AUTO)
+	    private Long id;
+
+    @ApiModelProperty("用户ID")
+	@TableField(value = "user_id_")
+    private Long userId;
+
+    @ApiModelProperty("用户类型")
+	@TableField(value = "client_type_")
+    private ClientEnum clientType;
+
+    @ApiModelProperty("发布作品ID")
+	@TableField(value = "user_music_id_")
+    private Long userMusicId;
+
+    @ApiModelProperty("创建时间")
+	@TableField(value = "create_time_")
+    private Date createTime;
+
+}

+ 28 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/UserMusicMapper.java

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 用户曲目作品
+ * 2023-09-05 15:27:10
+ */
+@Repository
+public interface UserMusicMapper extends BaseMapper<UserMusic> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<UserMusicWrapper.UserMusic>
+	 * @param param UserMusicWrapper.UserMusicQuery
+	 * @return List<UserMusicWrapper.UserMusic>
+	 */
+	List<UserMusicWrapper.UserMusic> selectPage(@Param("page") IPage<UserMusicWrapper.UserMusic> page, @Param("param") UserMusicWrapper.UserMusicQuery param);
+
+    void updateStar(@Param("userMusicId") Long userMusicId);
+}

+ 28 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/UserMusicStarMapper.java

@@ -0,0 +1,28 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 用户曲目作品点赞记录
+ * 2023-10-30 14:59:53
+ */
+@Repository
+public interface UserMusicStarMapper extends BaseMapper<UserMusicStar> {
+
+	/**
+	 * 分页查询
+	 * @param page IPage<UserMusicStarWrapper.UserMusicStar>
+	 * @param param UserMusicStarWrapper.UserMusicStarQuery
+	 * @return List<UserMusicStarWrapper.UserMusicStar>
+	 */
+	List<UserMusicStar> selectPage(@Param("page") IPage<UserMusicStar> page, @Param("param") UserMusicStarWrapper.UserMusicStarQuery param);
+
+    List<UserMusicStarWrapper.StarCount> getStarCountMapByUserMusicIds(@Param("userMusicIds") List<Long> userMusicIds);
+}

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

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

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

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.service;
 
 import java.util.List;
+import java.util.Map;
 
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.queryInfo.SubjectQueryInfo;
@@ -51,4 +52,6 @@ public interface SubjectService extends BaseService<Long, Subject> {
 	 * @return: java.util.List<com.yonge.cooleshow.biz.dal.vo.SubjectSelectVo>
 	 */
 	List<Subject> subjectSelect(String type, String userExtSubjectIds);
+
+    Map<Integer, Subject> getMapByIds(List<String> subjectIds);
 }

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

@@ -6,6 +6,7 @@ import com.yonge.cooleshow.biz.dal.queryInfo.SysMusicCompareRecordQueryInfo;
 import com.yonge.toolset.base.page.PageInfo;
 import com.yonge.toolset.mybatis.service.BaseService;
 
+import java.util.List;
 import java.util.Map;
 
 public interface SysMusicCompareRecordService extends BaseService<Long, SysMusicCompareRecord> {
@@ -60,4 +61,6 @@ public interface SysMusicCompareRecordService extends BaseService<Long, SysMusic
 
     //训练时长榜
     SysMusicCompareRecordQueryInfo.StatDto rankingList(SysMusicCompareRecordQueryInfo.StudentCompareRecordQueryInfo queryInfo);
+
+    Map<Long, SysMusicCompareRecord> getMapByIds(List<Long> musicPracticeRecordIds);
 }

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

@@ -17,6 +17,7 @@ import com.yonge.cooleshow.biz.dal.wrapper.teacher.TeacherWrapper;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * 教师表 服务类
@@ -183,4 +184,6 @@ public interface TeacherService extends IService<Teacher> {
     void updateTenant(TeacherWrapper.UpdateTenant updateTenant,Long userId);
 
     UserPaymentOrderWrapper.AccountTenantTo teacherSettlementFrom(Long teacherId,Long recomUserId);
+
+    Map<Long, Teacher> getMapByIds(List<Long> teacherIds);
 }

+ 66 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserMusicService.java

@@ -0,0 +1,66 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.biz.dal.entity.UserMusic;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户曲目作品
+ * 2023-09-05 15:27:10
+ */
+public interface UserMusicService extends IService<UserMusic>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return UserMusic
+     */
+	UserMusic detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<UserMusic>
+     * @param query UserMusicWrapper.UserMusicQuery
+     * @return IPage<UserMusic>
+     */
+    IPage<UserMusicWrapper.UserMusic> selectPage(IPage<UserMusicWrapper.UserMusic> page, UserMusicWrapper.UserMusicQuery query);
+
+    /**
+     * 添加
+     * @param userMusic UserMusicWrapper.UserMusic
+     * @return Boolean
+     */
+     Boolean add(UserMusicWrapper.UserMusic userMusic);
+
+    /**
+     * 更新
+     * @param userMusic UserMusicWrapper.UserMusic
+     * @return Boolean
+     */
+     Boolean update(UserMusicWrapper.UserMusic userMusic);
+
+    /**
+     *  根据曲目练习记录获取发布曲目
+     *
+     * @param musicPracticeRecordIds 曲目练习记录ID
+     */
+    Map<Long, UserMusic> getMapByMusicPracticeRecordIds(List<Long> musicPracticeRecordIds);
+
+
+    /**
+     * 保存草稿/发布作品
+     *
+     */
+    void save(UserMusicWrapper.AddUserMusic userMusic);
+
+    /**
+     * 分页
+     *
+     */
+    IPage<UserMusicWrapper.UserMusic> selectPage(IPage<UserMusicWrapper.UserMusic> page, UserMusicWrapper.UserMusicQuery query, JwtUserInfo<?> userInfo);
+}

+ 63 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserMusicStarService.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 用户曲目作品点赞记录
+ * 2023-10-30 14:59:53
+ */
+public interface UserMusicStarService extends IService<UserMusicStar>  {
+
+	/**
+     * 查询详情
+     * @param id 详情ID
+     * @return UserMusicStar
+     */
+	UserMusicStar detail(Long id);
+
+    /**
+     * 分页查询
+     * @param page IPage<UserMusicStar>
+     * @param query UserMusicStarWrapper.UserMusicStarQuery
+     * @return IPage<UserMusicStar>
+     */
+    IPage<UserMusicStarWrapper.UserMusicStar> selectPage(IPage<UserMusicStar> page, UserMusicStarWrapper.UserMusicStarQuery query);
+
+    /**
+     * 添加
+     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
+     * @return Boolean
+     */
+     Boolean add(UserMusicStarWrapper.UserMusicStar userMusicStar);
+
+    /**
+     * 更新
+     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
+     * @return Boolean
+     */
+     Boolean update(UserMusicStarWrapper.UserMusicStar userMusicStar);
+
+    /**
+     * 点赞/取消点赞
+     */
+    void star(UserMusicStarWrapper.Star star);
+
+    /**
+     *
+     * 查询点赞数
+     *
+     */
+    Map<Long,Integer> getStarCountMapByUserMusicIds(List<Long> userMusicIds);
+
+    /**
+     * 是否点赞
+     *
+     */
+    Map<Long,Boolean> getStarFlagMapByUserMusicIds(List<Long> userMusicIds, String clientType, String userId);
+}

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

@@ -58,6 +58,7 @@ import org.redisson.api.RMap;
 import org.redisson.api.RedissonClient;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.parameters.P;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -69,6 +70,7 @@ import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 
@@ -636,6 +638,16 @@ public class StudentServiceImpl extends ServiceImpl<StudentDao, Student> impleme
         }
     }
 
+    @Override
+    public Map<Long, Student> getMapByIds(List<Long> userIds) {
+        if (CollectionUtils.isEmpty(userIds)) {
+            return new HashMap<>();
+        }
+        List<Student> students = baseMapper.selectBatchIds(userIds);
+        return students.stream().collect(Collectors.toMap(Student::getUserId, Function.identity()));
+
+    }
+
     private Boolean updateStudent(StudentWrapper.Student studentInfo) {
         StudentVo student = detail(studentInfo.getId());
         if (student == null) {

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

@@ -1,9 +1,6 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
@@ -171,6 +168,22 @@ public class SubjectServiceImpl extends BaseServiceImpl<Long, Subject> implement
         return parents;
     }
 
+    @Override
+    public Map<Integer, Subject> getMapByIds(List<String> subjectIds) {
+
+        if(CollectionUtils.isEmpty(subjectIds)){
+            return new HashMap<>();
+        }
+
+        List<Subject> subjectList = subjectDao.findBySubjectByIdList(subjectIds.stream()
+            .filter(StringUtils::isNotBlank).collect(Collectors.joining(",")));
+        if(CollectionUtils.isEmpty(subjectList)){
+            return new HashMap<>();
+        }
+
+        return subjectList.stream().collect(Collectors.toMap(o -> o.getId().intValue(), o -> o));
+    }
+
     /***
      * 查询声部树
      * @param: sub

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

@@ -60,6 +60,9 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	@Autowired
 	private SysMusicCompareWeekDataService sysMusicCompareWeekDataService;
 
+    @Autowired
+    private UserMusicService userMusicService;
+
 	@Override
 	public BaseDAO<Long, SysMusicCompareRecord> getDAO() {
 		return sysMusicCompareRecordDao;
@@ -296,6 +299,16 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 		if(Objects.nonNull(sysMusicScore)){
 			jsonObject.put("sysMusicScoreName", sysMusicScore.getMusicSheetName());
 		}
+
+
+        // 上传过作品,用作品视频路径覆盖上传视频路径
+        // ID集合
+        Map<Long, UserMusic> userMusicMap = userMusicService.getMapByMusicPracticeRecordIds(Lists.newArrayList(recordId));
+
+        UserMusic userMusic = userMusicMap.get(recordId);
+        if (Objects.nonNull(userMusic)) {
+            jsonObject.put("videoFilePath", userMusic.getVideoUrl());
+        }
 		return jsonObject;
 	}
 
@@ -502,6 +515,16 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 		return result;
     }
 
+    @Override
+    public Map<Long, SysMusicCompareRecord> getMapByIds(List<Long> musicPracticeRecordIds) {
+        if (CollectionUtils.isEmpty(musicPracticeRecordIds)) {
+            return Collections.emptyMap();
+        }
+        List<SysMusicCompareRecord> list = sysMusicCompareRecordDao.selectByIds(musicPracticeRecordIds);
+
+        return list.stream().collect(Collectors.toMap(SysMusicCompareRecord::getId, o ->o));
+    }
+
 
     private String getExpireTime() {
 

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

@@ -1184,4 +1184,19 @@ public class TeacherServiceImpl extends ServiceImpl<TeacherDao, Teacher> impleme
 
         return accountTenantTo;
     }
+
+    @Override
+    public Map<Long, Teacher> getMapByIds(List<Long> teacherIds) {
+
+        if (CollectionUtils.isEmpty(teacherIds)) {
+            return Collections.emptyMap();
+        }
+
+        List<Teacher> teachers = getBaseMapper().selectBatchIds(teacherIds);
+        if (CollectionUtils.isEmpty(teachers)) {
+            return Collections.emptyMap();
+        }
+
+        return teachers.stream().collect(Collectors.toMap(Teacher::getUserId, o -> o, (o, n) -> n));
+    }
 }

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

@@ -0,0 +1,329 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.microsvc.toolkit.common.webportal.exception.BizException;
+import com.microsvc.toolkit.config.jwt.utils.JwtUserInfo;
+import com.yonge.cooleshow.biz.dal.entity.*;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.enums.EUserMusicType;
+import com.yonge.toolset.base.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 用户曲目作品
+ * 2023-09-05 15:27:10
+ */
+@Slf4j
+@Service
+public class UserMusicServiceImpl extends ServiceImpl<UserMusicMapper, UserMusic> implements UserMusicService {
+
+
+
+    @Autowired
+    private UserMusicService userMusicService;
+
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+    @Autowired
+    private MusicSheetService musicSheetService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @Autowired
+    private UserMusicStarService userMusicStarService;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+
+    /**
+     * 查询详情
+     * @param id 详情ID
+     * @return UserMusic
+     */
+	@Override
+    public UserMusic detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<UserMusic>
+     * @param query UserMusicWrapper.UserMusicQuery
+     * @return IPage<UserMusic>
+     */
+    @Override
+    public IPage<UserMusicWrapper.UserMusic> selectPage(IPage<UserMusicWrapper.UserMusic> page, UserMusicWrapper.UserMusicQuery query) {
+
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
+
+    /**
+     * 添加
+     * @param userMusic UserMusicWrapper.UserMusic
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(UserMusicWrapper.UserMusic userMusic) {
+
+        return this.save(JSON.parseObject(userMusic.jsonString(), UserMusic.class));
+    }
+
+    /**
+     * 更新
+     * @param userMusic UserMusicWrapper.UserMusic
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(UserMusicWrapper.UserMusic userMusic){
+
+        return this.updateById(JSON.parseObject(userMusic.jsonString(), UserMusic.class));
+    }
+
+
+    /**
+     *  根据曲目练习记录获取发布曲目
+     *
+     * @param musicPracticeRecordIds 曲目练习记录ID
+     * @return
+     */
+    @Override
+    public Map<Long, UserMusic> getMapByMusicPracticeRecordIds(List<Long> musicPracticeRecordIds) {
+        if (CollectionUtils.isEmpty(musicPracticeRecordIds)) {
+            return new HashMap<>();
+        }
+        List<UserMusic> list = this.lambdaQuery()
+            .in(UserMusic::getMusicPracticeRecordId, musicPracticeRecordIds)
+            .eq(UserMusic::getType, EUserMusicType.FORMAL)
+            .eq(UserMusic::getDelFlag, false)
+            .list();
+        if (CollectionUtils.isEmpty(list)) {
+            return new HashMap<>();
+        }
+        return list.stream().collect(java.util.stream.Collectors.toMap(UserMusic::getMusicPracticeRecordId, v -> v, (v1, v2) -> v1));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void save(UserMusicWrapper.AddUserMusic userMusic) {
+
+        // 设置曲目ID
+        if (userMusic.getMusicPracticeRecordId() != null) {
+            SysMusicCompareRecord practiceRecord = sysMusicCompareRecordService.get(userMusic.getMusicPracticeRecordId());
+            if (practiceRecord == null) {
+                throw new BizException("练习记录不存在");
+            }
+            userMusic.setMusicSheetId(practiceRecord.getMusicSheetId());
+            List<UserMusic> list = userMusicService.lambdaQuery()
+                .eq(UserMusic::getMusicPracticeRecordId, userMusic.getMusicPracticeRecordId())
+                .eq(UserMusic::getUserId, userMusic.getUserId())
+                .eq(UserMusic::getClientType, userMusic.getClientType())
+                .eq(UserMusic::getDelFlag, false)
+                .orderByAsc(UserMusic::getId)
+                .list();
+            if (!CollectionUtils.isEmpty(list)) {
+                userMusic.setId(list.get(0).getId());
+            }
+        }
+
+        // 设置默认封面
+        if (userMusic.getId() == null && StringUtils.isEmpty(userMusic.getImg()) && userMusic.getMusicSheetId() != null) {
+            MusicSheet sheet = musicSheetService.getById(userMusic.getMusicSheetId());
+            if (sheet != null) {
+                userMusic.setImg(sheet.getTitleImg());
+            }
+        }
+        // 设置视频默认封面
+        if (userMusic.getId() == null && StringUtil.isEmpty(userMusic.getVideoImg())) {
+            String value = sysConfigService.findConfigValue(SysConfigConstant.USER_MUSIC_VIDEO_DEFAULT_URL);
+            userMusic.setVideoImg(value);
+        }
+        UserMusic entity = JSON.parseObject(JSON.toJSONString(userMusic), UserMusic.class);
+
+        UserMusic old = null;
+        if (entity.getId() != null) {
+            old = userMusicService.getById(entity.getId());
+            if (old.getType() == EUserMusicType.FORMAL && entity.getType() == EUserMusicType.DRAFT) {
+                throw new BizException("已发布的作品不能修改为草稿");
+            }
+        }
+
+        if (entity.getType() == null) {
+        } else if (entity.getType().equals(EUserMusicType.DRAFT)) {
+            entity.setSubmitTime(null);
+        } else if (old == null || old.getType().equals(EUserMusicType.DRAFT)) {
+            entity.setSubmitTime(new Date());
+        }
+        userMusicService.saveOrUpdate(entity);
+    }
+
+    /**
+     * 分页
+     *
+     */
+    @Override
+    public IPage<UserMusicWrapper.UserMusic> selectPage(IPage<UserMusicWrapper.UserMusic> page, UserMusicWrapper.UserMusicQuery query, JwtUserInfo<?> userInfo) {
+        // 推荐作品 排序 同曲目同声部点赞降序>其他曲目同声部点赞降序
+        if (query.getSort() !=null && query.getSort() == 1) {
+            if (query.getExclusionId() != null) {
+                UserMusic userMusic = userMusicService.getById(query.getExclusionId());
+                if (userMusic != null) {
+                    query.setClientType(userMusic.getClientType());
+                    query.setUserId(userMusic.getUserId());
+                }
+            }
+        }
+        IPage<UserMusicWrapper.UserMusic> userMusicIPage = userMusicService.selectPage(page, query);
+        List<UserMusicWrapper.UserMusic> records = userMusicIPage.getRecords();
+        if (CollectionUtils.isEmpty(records)) {
+            return userMusicIPage;
+        }
+
+        // id集合
+        List<Long> ids = records.stream().map(UserMusicWrapper.UserMusic::getId).collect(Collectors.toList());
+
+        // 是否点赞
+        if (userInfo != null) {
+            Map<Long, Boolean> starFlagMapByUserMusicIds = userMusicStarService.getStarFlagMapByUserMusicIds(ids, userInfo.getClientType(), userInfo.getUserId());
+            for (UserMusicWrapper.UserMusic record : records) {
+                Boolean starFlag = starFlagMapByUserMusicIds.get(record.getId());
+                if (starFlag != null) {
+                    record.setStarFlag(starFlag);
+                }
+            }
+        }
+
+        // 评测记录ID集合
+        List<Long> musicPracticeRecordIds = records.stream()
+            .map(UserMusicWrapper.UserMusic::getMusicPracticeRecordId).collect(Collectors.toList());
+        Map<Long, SysMusicCompareRecord> recordMap = sysMusicCompareRecordService.getMapByIds(musicPracticeRecordIds);
+        for (UserMusicWrapper.UserMusic record : records) {
+            SysMusicCompareRecord musicPracticeRecord = recordMap.get(record.getMusicPracticeRecordId());
+            if (musicPracticeRecord != null) {
+                record.setRecordFilePath(musicPracticeRecord.getRecordFilePath());
+                record.setVideoFilePath(musicPracticeRecord.getVideoFilePath());
+            }
+        }
+
+        // 曲目ID集合
+        List<Long> musicSheetIds = records.stream().map(UserMusicWrapper.UserMusic::getMusicSheetId).collect(Collectors.toList());
+        Map<Long, MusicSheet> musicSheetMap = musicSheetService.getMapByIds(musicSheetIds);
+
+        for (UserMusicWrapper.UserMusic record : records) {
+            MusicSheet musicSheet = musicSheetMap.get(record.getMusicSheetId());
+            if (musicSheet != null) {
+                record.setMusicSheetName(musicSheet.getMusicSheetName());
+                record.setMusicSheetSubjectId(musicSheet.getMusicSubject());
+            }
+        }
+
+        // 用户ID集合
+
+        // 学生ID集合
+        List<Long> studentIds = records.stream().filter(o -> o.getClientType() == ClientEnum.STUDENT).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
+
+        Map<Long, Student> studentMap = studentService.getMapByIds(studentIds);
+
+
+        // 老师ID集合
+        List<Long> teacherIds = records.stream().filter(o -> o.getClientType() == ClientEnum.TEACHER).map(UserMusicWrapper.UserMusic::getUserId).collect(Collectors.toList());
+
+        Map<Long, Teacher> teacherMap = teacherService.getMapByIds(teacherIds);
+        studentIds.addAll(teacherIds);
+        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(studentIds);
+
+        String teacherAvatar = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR);
+        String studentAvatar = sysConfigService.findConfigValue(SysConfigConstant.STUDENT_AVATAR);
+
+
+        for (UserMusicWrapper.UserMusic record : records) {
+            SysUser sysUser = userMap.get(record.getUserId());
+            if (sysUser != null) {
+                record.setUsername(sysUser.getUsername());
+                record.setAvatar(sysUser.getAvatar());
+            }
+            if (record.getClientType() == ClientEnum.STUDENT) {
+                Student student = studentMap.get(record.getUserId());
+                if (student != null) {
+
+                    record.setSubjectId(student.getSubjectId());
+                    record.setVipFlag(student.getMembershipEndTime() != null && student.getMembershipEndTime().after(new Date()));
+                }
+                if (StringUtil.isEmpty(record.getAvatar())) {
+                    record.setAvatar(studentAvatar);
+                }
+            } else {
+                Teacher teacher = teacherMap.get(record.getUserId());
+                if (teacher != null) {
+                    record.setSubjectId(teacher.getSubjectId());
+                    record.setVipFlag(teacher.getMembershipEndTime() != null && teacher.getMembershipEndTime().after(new Date()));
+                }
+                if (StringUtil.isEmpty(record.getAvatar())) {
+                    record.setAvatar(teacherAvatar);
+                }
+            }
+        }
+
+        // 声部ID集合
+        List<String> subjectIds = records.stream().map(UserMusicWrapper.UserMusic::getSubjectId)
+            .filter(o -> !StringUtil.isEmpty(o))
+            .distinct().collect(Collectors.toList());
+
+        Map<Integer, Subject> subjectMap =
+            subjectService.getMapByIds(subjectIds);
+
+        for (UserMusicWrapper.UserMusic record : records) {
+
+            if (StringUtils.isNotBlank(record.getSubjectId())) {
+
+                List<Integer> collect = Arrays.stream(record.getSubjectId().split(",")).map(Integer::parseInt).collect(Collectors.toList());
+                List<Subject> subjects = new ArrayList<>();
+                for (Integer integer : collect) {
+                    Subject subject = subjectMap.get(integer);
+                    if (subject != null) {
+                        subjects.add(subject);
+                    }
+                }
+                record.setSubjectName(subjects.stream().map(Subject::getName).collect(Collectors.joining(",")));
+
+            }
+            if (StringUtil.isEmpty(record.getMusicSheetSubjectId())) {
+                continue;
+            }
+            Subject subject = subjectMap.get(Integer.parseInt(record.getMusicSheetSubjectId()));
+            if (subject != null) {
+                record.setMusicSheetSubjectName(subject.getName());
+            }
+        }
+
+
+        return userMusicIPage;
+    }
+}

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

@@ -0,0 +1,236 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.Subject;
+import com.yonge.cooleshow.biz.dal.entity.Teacher;
+import com.yonge.cooleshow.biz.dal.entity.UserMusicStar;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper;
+import com.yonge.cooleshow.biz.dal.mapper.UserMusicStarMapper;
+import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper;
+import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 用户曲目作品点赞记录
+ * 2023-10-30 14:59:53
+ */
+@Slf4j
+@Service
+public class UserMusicStarServiceImpl extends ServiceImpl<UserMusicStarMapper, UserMusicStar> implements UserMusicStarService {
+
+    @Autowired
+    private UserMusicMapper userMusicMapper;
+
+    @Autowired
+    private StudentService studentService;
+
+    @Autowired
+    private TeacherService teacherService;
+
+    @Autowired
+    private SubjectService subjectService;
+
+    @Autowired
+    private SysUserService sysUserService;
+
+    @Autowired
+    private SysConfigService sysConfigService;
+
+    /**
+     * 查询详情
+     * @param id 详情ID
+     * @return UserMusicStar
+     */
+    @Override
+    public UserMusicStar detail(Long id) {
+
+        return baseMapper.selectById(id);
+    }
+
+    /**
+     * 分页查询
+     * @param page IPage<UserMusicStar>
+     * @param query UserMusicStarWrapper.UserMusicStarQuery
+     * @return IPage<UserMusicStar>
+     */
+    @Override
+    public IPage<UserMusicStarWrapper.UserMusicStar> selectPage(IPage<UserMusicStar> page, UserMusicStarWrapper.UserMusicStarQuery query) {
+
+        IPage<UserMusicStar> pages = page.setRecords(baseMapper.selectPage(page, query));
+        IPage<UserMusicStarWrapper.UserMusicStar> musicStarIPage = pages.convert(o -> JSON.parseObject(JSON.toJSONString(o), UserMusicStarWrapper.UserMusicStar.class));
+
+        List<UserMusicStarWrapper.UserMusicStar> userMusicStars = musicStarIPage.getRecords();
+        if (CollectionUtils.isEmpty(userMusicStars)){
+            return musicStarIPage;
+        }
+
+        userMusicStars = JSON.parseArray(JSON.toJSONString(userMusicStars), UserMusicStarWrapper.UserMusicStar.class);
+
+        // 学生ID集合
+        List<Long> studentIds = userMusicStars.stream().filter(o -> o.getClientType() == ClientEnum.STUDENT)
+            .map(UserMusicStarWrapper.UserMusicStar::getUserId).collect(Collectors.toList());
+
+        Map<Long, Student> studentMap = studentService.getMapByIds(studentIds);
+
+
+        // 老师ID集合
+        List<Long> teacherIds = userMusicStars.stream().filter(o -> o.getClientType() == ClientEnum.TEACHER)
+            .map(UserMusicStarWrapper.UserMusicStar::getUserId).collect(Collectors.toList());
+
+        Map<Long, Teacher> teacherMap = teacherService.getMapByIds(teacherIds);
+        studentIds.addAll(teacherIds);
+        Map<Long, com.yonge.cooleshow.biz.dal.entity.SysUser> userMap = sysUserService.getMapByIds(studentIds);
+
+        String teacherAvatar = sysConfigService.findConfigValue(SysConfigConstant.TEACHER_AVATAR);
+        String studentAvatar = sysConfigService.findConfigValue(SysConfigConstant.STUDENT_AVATAR);
+        for (UserMusicStarWrapper.UserMusicStar userMusicStar : userMusicStars) {
+
+            com.yonge.cooleshow.biz.dal.entity.SysUser sysUser = userMap.get(userMusicStar.getUserId());
+            if (sysUser != null) {
+                userMusicStar.setUserName(sysUser.getUsername());
+                userMusicStar.setUserAvatar(sysUser.getAvatar());
+            }
+            if (userMusicStar.getClientType() == ClientEnum.STUDENT) {
+                Student student = studentMap.get(userMusicStar.getUserId());
+                if (student != null) {
+                    userMusicStar.setSubjectId(student.getSubjectId());
+                }
+                if (StringUtil.isEmpty(userMusicStar.getUserAvatar())) {
+                    userMusicStar.setUserAvatar(studentAvatar);
+                }
+            } else {
+                Teacher teacher = teacherMap.get(userMusicStar.getUserId());
+                if (teacher != null) {
+                    userMusicStar.setSubjectId(teacher.getSubjectId());
+                }
+                if (StringUtil.isEmpty(userMusicStar.getUserAvatar())) {
+                    userMusicStar.setUserAvatar(teacherAvatar);
+                }
+            }
+        }
+
+        // 声部ID集合
+        List<String> subjectIds = studentMap.values().stream().map(Student::getSubjectId).collect(Collectors.toList());
+        subjectIds.addAll(teacherMap.values().stream().map(Teacher::getSubjectId).collect(Collectors.toList()));
+
+        Map<Integer, Subject> subjectMap =
+            subjectService.getMapByIds(subjectIds);
+
+        for (UserMusicStarWrapper.UserMusicStar userMusicStar : userMusicStars) {
+
+
+            if (StringUtil.isEmpty(userMusicStar.getSubjectId())) {
+                continue;
+            }
+            if (StringUtils.isNotBlank(userMusicStar.getSubjectId())) {
+
+                List<Integer> collect = Arrays.stream(userMusicStar.getSubjectId().split(",")).map(Integer::parseInt).collect(Collectors.toList());
+                List<Subject> subjects = new ArrayList<>();
+                for (Integer integer : collect) {
+                    Subject subject = subjectMap.get(integer);
+                    if (subject != null) {
+                        subjects.add(subject);
+                    }
+                }
+                userMusicStar.setSubjectName(subjects.stream().map(Subject::getName).collect(Collectors.joining(",")));
+
+            }
+
+        }
+        return musicStarIPage.setRecords(userMusicStars);
+    }
+
+    /**
+     * 添加
+     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
+     * @return Boolean
+     */
+    @Override
+    public Boolean add(UserMusicStarWrapper.UserMusicStar userMusicStar) {
+
+        return this.save(JSON.parseObject(userMusicStar.jsonString(), UserMusicStar.class));
+    }
+
+    /**
+     * 更新
+     * @param userMusicStar UserMusicStarWrapper.UserMusicStar
+     * @return Boolean
+     */
+    @Override
+    public Boolean update(UserMusicStarWrapper.UserMusicStar userMusicStar){
+
+        return this.updateById(JSON.parseObject(userMusicStar.jsonString(), UserMusicStar.class));
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void star(UserMusicStarWrapper.Star star) {
+
+        this.lambdaUpdate()
+            .eq(UserMusicStar::getUserId, star.getUserId())
+            .eq(UserMusicStar::getUserMusicId, star.getUserMusicId())
+            .eq(UserMusicStar::getClientType, star.getClientType())
+            .remove();
+
+        if (star.getStar()) {
+            UserMusicStar userMusicStar = new UserMusicStar();
+            userMusicStar.setClientType(star.getClientType());
+            userMusicStar.setUserId(star.getUserId());
+            userMusicStar.setUserMusicId(star.getUserMusicId());
+            this.save(userMusicStar);
+        }
+        userMusicMapper.updateStar(star.getUserMusicId());
+
+
+    }
+
+    @Override
+    public Map<Long, Integer> getStarCountMapByUserMusicIds(List<Long> userMusicIds) {
+        if (CollectionUtils.isEmpty(userMusicIds)) {
+            return new HashMap<>();
+        }
+        List<UserMusicStarWrapper.StarCount> starCounts = baseMapper.getStarCountMapByUserMusicIds(userMusicIds);
+        Map<Long, Integer> starCountMap = new HashMap<>();
+        for (UserMusicStarWrapper.StarCount starCount : starCounts) {
+            starCountMap.put(starCount.getUserMusicId(), starCount.getStarCount());
+        }
+        return starCountMap;
+    }
+
+    @Override
+    public Map<Long, Boolean> getStarFlagMapByUserMusicIds(List<Long> userMusicIds, String clientType, String userId) {
+        if (CollectionUtils.isEmpty(userMusicIds)) {
+            return new HashMap<>();
+        }
+        if (StringUtil.isEmpty(clientType)) {
+            return new HashMap<>();
+        }
+        if (StringUtil.isEmpty(userId)) {
+            return new HashMap<>();
+        }
+        List<UserMusicStar> list = this.lambdaQuery()
+            .eq(UserMusicStar::getClientType, clientType)
+            .eq(UserMusicStar::getUserId, userId)
+            .in(UserMusicStar::getUserMusicId, userMusicIds)
+            .list();
+        if (CollectionUtils.isEmpty(list)) {
+            return new HashMap<>();
+        }
+        return list.stream().collect(Collectors.toMap(UserMusicStar::getUserMusicId, o->true, (k1, k2) -> k1));
+    }
+}

+ 135 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicStarWrapper.java

@@ -0,0 +1,135 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 用户曲目作品点赞记录
+ * 2023-10-30 14:59:53
+ */
+@ApiModel(value = "UserMusicStarWrapper对象", description = "用户曲目作品点赞记录查询对象")
+public class UserMusicStarWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" UserMusicStarQuery-用户曲目作品点赞记录")
+    public static class UserMusicStarQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        @ApiModelProperty("作品ID")
+        @NotNull(message = "作品ID不能为空")
+        private Long userMusicId;
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserMusicStarQuery from(String json) {
+            return JSON.parseObject(json, UserMusicStarQuery.class);
+        }
+    }
+
+    @Data
+	@ApiModel(" UserMusicStar-用户曲目作品点赞记录")
+    public static class UserMusicStar {
+
+
+        private Long id;
+
+        @ApiModelProperty("用户ID")
+        private Long userId;
+
+        @ApiModelProperty("用户类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("用户名")
+        private String userName;
+
+        @ApiModelProperty("用户头像")
+        private String userAvatar;
+
+        @ApiModelProperty(value = "用户声部ID")
+        private String subjectId;
+
+        @ApiModelProperty(value = "用户声部名称")
+        private String subjectName;
+
+        @ApiModelProperty("年级")
+        private Integer currentGradeNum;
+
+        @ApiModelProperty("班级")
+        private String currentClass;
+
+        @ApiModelProperty("发布作品ID")
+        private Long userMusicId;
+
+        @ApiModelProperty("创建时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserMusicStar from(String json) {
+            return JSON.parseObject(json, UserMusicStar.class);
+        }
+	}
+
+
+    @Data
+    @ApiModel(" Star-点赞/取消点赞")
+    public static class Star {
+
+        @ApiModelProperty("发布作品ID")
+        private Long userMusicId;
+
+        @ApiModelProperty("点赞/取消点赞")
+        private Boolean star = true;
+
+
+        @ApiModelProperty(value = "用户ID",hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "用户类型",hidden = true)
+        private ClientEnum clientType;
+
+
+    }
+
+    @Data
+    public static class StarCount {
+
+        @ApiModelProperty("发布作品ID")
+        private Long userMusicId;
+
+        @ApiModelProperty("点赞数")
+        private Integer starCount;
+
+    }
+}

+ 223 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/UserMusicWrapper.java

@@ -0,0 +1,223 @@
+package com.yonge.cooleshow.biz.dal.wrapper;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.common.enums.EUserMusicType;
+import com.microsvc.toolkit.common.response.paging.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Date;
+import java.util.Optional;
+
+/**
+ * 用户曲目作品
+ * 2023-09-05 15:27:10
+ */
+@ApiModel(value = "UserMusicWrapper对象", description = "用户曲目作品查询对象")
+public class UserMusicWrapper {
+
+    @Data
+	@Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @ApiModel(" UserMusicQuery-用户曲目作品")
+    public static class UserMusicQuery implements QueryInfo {
+
+    	@ApiModelProperty("当前页")
+        private Integer page;
+
+        @ApiModelProperty("分页行数")
+        private Integer rows;
+
+        @ApiModelProperty("关键字匹配")
+		private String keyword;
+
+        @ApiModelProperty("草稿 DRAFT 作品FORMAL")
+        private EUserMusicType type;
+
+        @ApiModelProperty(value = "用户ID",hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "用户类型",hidden = true)
+        private ClientEnum clientType;
+
+        @ApiModelProperty(value = "id",hidden = true)
+        private Long id;
+
+
+        @ApiModelProperty(value = "去除的ID,推荐作品列表需要去除原本作品")
+        private Long exclusionId;
+
+
+        @ApiModelProperty(value = "排序 1:推荐")
+        private Integer sort = 0;
+
+
+
+        public String getKeyword() {
+            return Optional.ofNullable(keyword).filter(StringUtils::isNotBlank).orElse(null);
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserMusicQuery from(String json) {
+            return JSON.parseObject(json, UserMusicQuery.class);
+        }
+    }
+
+    @Data
+	@ApiModel(" UserMusic-用户曲目作品")
+    public static class UserMusic {
+
+
+        private Long id;
+
+        @ApiModelProperty(value = "用户ID")
+        private Long userId;
+
+        @ApiModelProperty(value = "用户类型")
+        private ClientEnum clientType;
+
+        @ApiModelProperty(value = "用户名称")
+        private String username;
+
+        @ApiModelProperty(value = "用户头像")
+        private String avatar;
+
+        @ApiModelProperty(value = "用户声部ID")
+        private String subjectId;
+
+        @ApiModelProperty(value = "用户声部名称")
+        private String subjectName;
+
+
+        @ApiModelProperty("年级")
+        private Integer currentGradeNum;
+
+        @ApiModelProperty("班级")
+        private String currentClass;
+
+        @ApiModelProperty(value = "是否会员")
+        private Boolean vipFlag;
+
+        @ApiModelProperty("关联练习数据ID")
+        private Long musicPracticeRecordId;
+
+        @ApiModelProperty(value = "曲目ID")
+        private Long musicSheetId;
+
+
+        @ApiModelProperty("原伴奏")
+        private String accompanyUrl;
+
+        @ApiModelProperty("曲目名称")
+        private String musicSheetName;
+
+        @ApiModelProperty("曲目声部ID")
+        private String musicSheetSubjectId;
+
+        @ApiModelProperty("曲目声部名称")
+        private String musicSheetSubjectName;
+
+        @ApiModelProperty("草稿 DRAFT 作品FORMAL")
+        private EUserMusicType type;
+
+        @ApiModelProperty("封面图")
+        private String img;
+
+        @ApiModelProperty("视频地址")
+        private String videoUrl;
+
+        @ApiModelProperty("视频封面图")
+        private String videoImg;
+
+        @ApiModelProperty("录音文件地址")
+        private String recordFilePath;
+
+        @ApiModelProperty("录像文件地址")
+        private String videoFilePath;
+
+        @ApiModelProperty("json配置")
+        private String jsonConfig;
+
+        @ApiModelProperty("点赞数")
+        private Integer likeNum = 0;
+
+        @ApiModelProperty("发布描述")
+        private String desc;
+
+        @ApiModelProperty("是否点赞")
+        private Boolean starFlag =false;
+
+
+        @ApiModelProperty("发布作品时间")
+        private Date submitTime;
+
+        @ApiModelProperty("录制上传时间")
+        private Date createTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public static UserMusic from(String json) {
+            return JSON.parseObject(json, UserMusic.class);
+        }
+	}
+
+
+    @Data
+    @ApiModel(" UserMusic-用户曲目作品")
+    public static class AddUserMusic {
+
+
+        private Long id;
+
+        @ApiModelProperty(value = "用户ID",hidden = true)
+        private Long userId;
+
+        @ApiModelProperty(value = "用户类型",hidden = true)
+        private ClientEnum clientType;
+
+        @ApiModelProperty("关联练习数据ID")
+        private Long musicPracticeRecordId;
+
+        @ApiModelProperty(value = "曲目ID",hidden = true)
+        private Long musicSheetId;
+
+        @ApiModelProperty("原伴奏")
+        private String accompanyUrl;
+
+
+        @ApiModelProperty("草稿 DRAFT 作品FORMAL")
+        private EUserMusicType type;
+
+        @ApiModelProperty("封面图")
+        private String img;
+
+        @ApiModelProperty("视频封面图")
+        private String videoImg;
+
+
+        @ApiModelProperty("发布描述")
+        private String desc;
+
+
+        @ApiModelProperty("视频地址")
+        private String videoUrl;
+
+        @ApiModelProperty("json配置")
+        private String jsonConfig;
+
+    }
+
+}

+ 7 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -549,6 +549,13 @@
 		FROM sys_music_compare_record smcr
 		WHERE user_id_=#{userId} AND monday_ = #{monday}
 	</select>
+
+	<select id="selectByIds" resultMap="SysMusicCompareRecord">
+        select * from sys_music_compare_record where id_ in
+        <foreach collection="musicPracticeRecordIds" item="musicPracticeRecordId" open="(" close=")" separator=",">
+            #{musicPracticeRecordId}
+        </foreach>
+    </select>
     <!--曲目练习统计-->
 
 </mapper>

+ 46 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicMapper.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.UserMusicMapper">
+
+
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.wrapper.UserMusicWrapper$UserMusic">
+		SELECT
+            t.*
+		FROM user_music t
+        left join music_sheet t1 on t1.id_ = t.music_sheet_id_
+        <where>
+            t.del_flag_ = 0
+            <if test="param.keyword != null and param.keyword != ''">
+                and t1.music_sheet_name_ like concat('%', #{param.keyword}, '%')
+            </if>
+            <if test="param.userId != null">
+                and t.user_id_ = #{param.userId}
+            </if>
+            <if test="param.clientType != null">
+                and t.client_type_ = #{param.clientType}
+            </if>
+            <if test="param.type != null">
+                and t.type_ = #{param.type}
+            </if>
+            <if test="param.id != null">
+                and t.id_ = #{param.id}
+            </if>
+            <if test="param.exclusionId != null">
+                and t.id_ != #{param.exclusionId}
+            </if>
+        </where>
+        <if test="param.sort != null">
+            order by
+            <if test="param.sort == 1">
+                t.like_num_ desc,
+            </if>
+            t.submit_time_ desc ,t.create_time_ desc ,t.id_ desc
+        </if>
+
+	</select>
+
+    <update id="updateStar">
+        update user_music set like_num_ =(select count(1) from  user_music_star where  user_music_id_ = #{userMusicId}) where id_ = #{userMusicId}
+    </update>
+</mapper>

+ 42 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserMusicStarMapper.xml

@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.yonge.cooleshow.biz.dal.mapper.UserMusicStarMapper">
+
+
+
+    <!-- 表字段 -->
+    <sql id="baseColumns">
+         t.id_ AS id
+        , t.user_id_ AS userId
+        , t.client_type_ AS clientType
+        , t.user_music_id_ AS userMusicId
+        , t.create_time_ AS createTime
+        </sql>
+
+    <select id="selectPage" resultType="com.yonge.cooleshow.biz.dal.entity.UserMusicStar">
+		SELECT
+        	<include refid="baseColumns" />
+		FROM user_music_star t
+        <where>
+            <if test="param.userMusicId != null">
+                AND t.user_music_id_ = #{param.userMusicId}
+            </if>
+        </where>
+        order by t.create_time_ desc ,t.id_ desc
+	</select>
+
+    <select id="getStarCountMapByUserMusicIds"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.UserMusicStarWrapper$StarCount">
+        SELECT
+            t.user_music_id_ AS userMusicId,
+            count(1) AS starCount
+        FROM user_music_star t
+        WHERE t.user_music_id_ IN
+        <foreach collection="userMusicIds" item="userMusicId" separator="," open="(" close=")">
+            #{userMusicId}
+        </foreach>
+        GROUP BY t.user_music_id_
+
+
+    </select>
+</mapper>