Bladeren bron

Merge branch 'dev_v1.3.6_20221021' into online

Eric 2 jaren geleden
bovenliggende
commit
fddfe87a04
63 gewijzigde bestanden met toevoegingen van 2273 en 279 verwijderingen
  1. 9 2
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/controller/NewsController.java
  2. 1 1
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/controller/queryinfo/NewsInformationQueryInfo.java
  3. 1 1
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/dal/entity/SysNewsInformation.java
  4. 12 0
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/dto/AppHomeDto.java
  5. 1 1
      cooleshow-cms/src/main/resources/config/mybatis/SysNewsInformationMapper.xml
  6. 13 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicAlbumController.java
  7. 2 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java
  8. 21 14
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicTagController.java
  9. 130 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/music/MusicCompareRecordStatController.java
  10. 6 3
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java
  11. 217 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/music/MusicCompareVo.java
  12. 0 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicFavoriteDao.java
  13. 6 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicSheetDao.java
  14. 1 12
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicTagDao.java
  15. 20 8
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareRecordDao.java
  16. 51 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/AppMusicSheetVo.java
  17. 25 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/MusicTagSaveDto.java
  18. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicSheetSearch.java
  19. 11 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/MusicTagSearch.java
  20. 73 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicCompareRecordStat.java
  21. 25 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheet.java
  22. 26 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicTag.java
  23. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/FeatureType.java
  24. 2 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/HeardLevelEnum.java
  25. 37 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/MusicSortType.java
  26. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/coupon/CouponCategoryEnum.java
  27. 59 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/music/MusicCompareType.java
  28. 45 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/MusicCompareRecordStatMapper.java
  29. 10 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysMusicCompareRecordQueryInfo.java
  30. 49 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicCompareRecordStatService.java
  31. 6 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicFavoriteService.java
  32. 2 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicTagService.java
  33. 229 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicCompareRecordStatServiceImp.java
  34. 8 2
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicFavoriteServiceImpl.java
  35. 44 43
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  36. 41 83
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicTagServiceImpl.java
  37. 139 20
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/SysMusicCompareRecordServiceImpl.java
  38. 13 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetDetailVo.java
  39. 0 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetVo.java
  40. 22 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicTagVo.java
  41. 4 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StatGroupWrapper.java
  42. 340 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/music/MusicCompareWrapper.java
  43. 130 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicCompareRecordStatMapper.xml
  44. 0 5
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicFavoriteMapper.xml
  45. 41 19
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml
  46. 1 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetPracticeRecordMapper.xml
  47. 15 29
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicTagMapper.xml
  48. 37 2
      cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml
  49. 1 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/ResourceServerConfig.java
  50. 73 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java
  51. 2 2
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/MusicTagController.java
  52. 23 1
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java
  53. 1 0
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysMusicCompareRecordController.java
  54. 1 1
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/ResourceServerConfig.java
  55. 74 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java
  56. 2 2
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicTagController.java
  57. 44 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/StudentController.java
  58. 84 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/SysMusicCompareRecordController.java
  59. 9 0
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenShareController.java
  60. 1 1
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/config/ResourceServerConfig.java
  61. 1 0
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/MusicSheetController.java
  62. 2 2
      cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/open/OpenMusicTagController.java
  63. 15 0
      service.md

+ 9 - 2
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/controller/NewsController.java

@@ -113,7 +113,7 @@ public class NewsController extends BaseController {
 				}
 			}
 		}
-		if(newsInfo.getType() == 4 ||newsInfo.getType() == 5) {
+		if(newsInfo.getType() == 4 ||newsInfo.getType() == 5||newsInfo.getType() == 7) {
 			if (StringUtil.isEmpty(newsInfo.getClientType() )) {
 				return failed("平台不能为空");
 			}
@@ -133,7 +133,7 @@ public class NewsController extends BaseController {
 			}
 		}
 		// 2 3 4
-		if (newsInfo.getType() == 2 ||newsInfo.getType() == 3 ||newsInfo.getType() == 4 ) {
+		if (newsInfo.getType() == 2 ||newsInfo.getType() == 3 ||newsInfo.getType() == 4||newsInfo.getType() == 7 ) {
 			if (newsInfo.getOnlineTime() == null || newsInfo.getOfflineTime() == null) {
 				return failed("生效时间不能为空");
 			}
@@ -273,6 +273,13 @@ public class NewsController extends BaseController {
 		params = new HashMap<>();
 		MapUtil.populateMap(params, queryInfo);
 		appHomeDto.setBanner(sysNewsInformationService.selectPage(queryInfo).getRows());
+
+		// 悬浮框
+		queryInfo.setType(7);
+		params = new HashMap<>();
+		MapUtil.populateMap(params, queryInfo);
+		appHomeDto.setSuspension(sysNewsInformationService.selectPage(queryInfo).getRows());
+
 		// 闪页
 		queryInfo.setType(3);
 		params = new HashMap<>();

+ 1 - 1
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/controller/queryinfo/NewsInformationQueryInfo.java

@@ -10,7 +10,7 @@ import java.util.List;
 
 public class NewsInformationQueryInfo extends QueryInfo {
 
-	@ApiModelProperty(value = "类型,1热门资讯,2开屏广告,3闪页管理,4轮播图管理 5按钮管理 6 乐理章节", required = true)
+	@ApiModelProperty(value = "类型,1热门资讯,2开屏广告,3闪页管理,4轮播图管理 5按钮管理 6 乐理章节 7 悬浮窗设置 ", required = true)
 	@NotNull(message = "类型不能为空")
 	private Integer type;
 

+ 1 - 1
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/dal/entity/SysNewsInformation.java

@@ -35,7 +35,7 @@ public class SysNewsInformation {
 	private String videoCoverImage;
 
 	/** 类型 */
-	@ApiModelProperty(value = "类型,1热门资讯,2开屏广告,3闪页管理,4轮播图管理 5app按钮管理 6:乐理章节", required = true)
+	@ApiModelProperty(value = "类型,1热门资讯,2开屏广告,3闪页管理,4轮播图管理 5app按钮管理 6:乐理章节 7 悬浮窗设置", required = true)
 	@NotNull(message = "类型不能为空")
 	private Integer type;
 	

+ 12 - 0
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/dto/AppHomeDto.java

@@ -21,12 +21,24 @@ public class AppHomeDto {
     @ApiModelProperty("banner")
     private List<SysNewsInformationDto> banner;
 
+
+    @ApiModelProperty("悬浮框")
+    private List<SysNewsInformationDto> suspension;
+
     @ApiModelProperty("闪页")
     private List<SysNewsInformationDto> flashPage;
 
     @ApiModelProperty("app按钮")
     private List<SysNewsInformationDto> appMenu;
 
+    public List<SysNewsInformationDto> getSuspension() {
+        return suspension;
+    }
+
+    public void setSuspension(List<SysNewsInformationDto> suspension) {
+        this.suspension = suspension;
+    }
+
     public List<SysNewsInformationDto> getInformation() {
         return information;
     }

+ 1 - 1
cooleshow-cms/src/main/resources/config/mybatis/SysNewsInformationMapper.xml

@@ -69,7 +69,7 @@
 						and if(sni.online_time_ is not null,sni.online_time_ &lt;= now(),1=1)
 						and if(sni.offline_time_ is not null,sni.offline_time_ &gt;= now(),1=1)
 					</if>
-					<if test="type == 4 or type == 5">
+					<if test="type == 4 or type == 5  or type == 7">
 						<choose>
 							<when test="platformType == 'WEBSITE'">
 								and sni.client_type_ = #{platformType}

+ 13 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicAlbumController.java

@@ -12,6 +12,7 @@ import com.yonge.cooleshow.biz.dal.entity.MusicAlbum;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.service.MusicAlbumService;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
+import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.cooleshow.biz.dal.vo.AlbumDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicAlbumVo;
@@ -53,6 +54,12 @@ public class MusicAlbumController extends BaseController {
             return failed("用户信息获取失败");
         }
 
+
+        String[] split = musicAlbum.getAlbumTag().split(",");
+        if (split.length >3) {
+            throw new BizException("专辑标签数不能超过3个");
+        }
+
         musicAlbum.setCreateBy(sysUser.getId());
         musicAlbum.setCreateTime(new Date());
         musicAlbum.setUpdateBy(sysUser.getId());
@@ -88,6 +95,12 @@ public class MusicAlbumController extends BaseController {
         if (YesOrNoEnum.YES.getCode().equals(service.getAlbumStatus().getCode())) {
             return failed("启用状态不许修改");
         }
+
+        String[] split = musicAlbum.getAlbumTag().split(",");
+        if (split.length >3) {
+            throw new BizException("专辑标签数不能超过3个");
+        }
+
         musicAlbum.setUpdateBy(sysUser.getId());
         musicAlbum.setUpdateTime(new Date());
         return succeed(musicAlbumService.updateMusicAlbum(musicAlbum));

+ 2 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicSheetController.java

@@ -126,9 +126,11 @@ public class MusicSheetController extends BaseController {
 
         musicSheetDto.setUserId(sysUser.getId());
         musicSheetDto.setAuditStatus(AuthStatusEnum.PASS);
+        musicSheetDto.setFirstPassAuditTime(new Date());
         musicSheetDto.setDelFlag(false);
         musicSheetDto.setSourceType(SourceTypeEnum.PLATFORM);
 
+        musicSheetDto.setFavoriteCount(0);
         musicSheetDto.setCreateBy(sysUser.getId());
         musicSheetDto.setCreateTime(new Date());
         musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());

+ 21 - 14
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/MusicTagController.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.admin.controller;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.dto.AdjustModel;
 import com.yonge.cooleshow.biz.dal.dto.MusicTagSaveDto;
 import com.yonge.cooleshow.biz.dal.dto.search.MusicTagSearch;
 import com.yonge.cooleshow.biz.dal.entity.MusicTag;
@@ -57,8 +58,8 @@ public class MusicTagController extends BaseController {
 	 */
 	@GetMapping("/tree")
 	@ApiOperation(value = "查询标签树列表")
-	public HttpResponseResult<List<MusicTagVo>> tree() {
-		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree();
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
 		return succeed(treeList);
 	}
 
@@ -69,12 +70,7 @@ public class MusicTagController extends BaseController {
 	@ApiOperation(value = "新增", httpMethod="POST", consumes="application/json", produces="application/json")
 	@PreAuthorize("@pcs.hasPermissions('MusicTag/save')")
 	public HttpResponseResult<Boolean> save(@Validated(MusicTagSaveDto.Create.class) @RequestBody MusicTagSaveDto musicTagSaveDto) {
-		if (musicTagSaveDto.getParentTagId() != null && musicTagSaveDto.getParentTagId() != 0) {
-			MusicTag musicTag = musicTagService.getById(musicTagSaveDto.getParentTagId());
-			if (musicTag.getParentTagId() != 0) {
-				return failed("标签只能有两级");
-			}
-		}
+
 		return succeed(musicTagService.createMusicTag(musicTagSaveDto));
 	}
 
@@ -85,12 +81,6 @@ public class MusicTagController extends BaseController {
 	@ApiOperation(value = "修改", httpMethod="POST", consumes="application/json", produces="application/json")
 	@PreAuthorize("@pcs.hasPermissions('MusicTag/update')")
 	public HttpResponseResult<Boolean> update(@Validated(MusicTagSaveDto.Update.class) @RequestBody MusicTagSaveDto musicTagSaveDto) {
-		if (musicTagSaveDto.getParentTagId() != null && musicTagSaveDto.getParentTagId() != 0) {
-			MusicTag musicTag = musicTagService.getById(musicTagSaveDto.getParentTagId());
-			if (musicTag.getParentTagId() != 0) {
-				return failed("标签只能有两级");
-			}
-		}
 		return succeed(musicTagService.updateMusicTag(musicTagSaveDto));
 	}
 
@@ -119,4 +109,21 @@ public class MusicTagController extends BaseController {
 		}
 		return status(musicTagService.state(id));
 	}
+
+
+	/**
+	 * 设置排序值 和加精
+	 */
+	@PostMapping("/adjust")
+	@ApiOperation(value = "标签调整设置")
+	public HttpResponseResult<Boolean> adjust(@RequestBody @Valid AdjustModel model) {
+
+		MusicTag musicTag = new MusicTag();
+		musicTag.setId(model.getId());
+		musicTag.setSortNumber(model.getSort());
+
+		musicTagService.updateById(musicTag);
+
+		return succeed();
+	}
 }

+ 130 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/music/MusicCompareRecordStatController.java

@@ -0,0 +1,130 @@
+package com.yonge.cooleshow.admin.controller.music;
+
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.admin.io.request.music.MusicCompareVo;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.service.MusicCompareRecordStatService;
+import com.yonge.cooleshow.biz.dal.service.SysMusicCompareRecordService;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.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.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;
+
+/**
+ * <p>
+ * 曲目练习统计表 前端控制器
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+@RestController
+@RequestMapping("/music/compare")
+@Api(tags = "曲目练习统计 ")
+public class MusicCompareRecordStatController extends BaseController {
+
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private MusicCompareRecordStatService musicCompareRecordStatService;
+    @Autowired
+    private SysMusicCompareRecordService sysMusicCompareRecordService;
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目统计汇总信息", notes = "")
+    @PostMapping(value = "/record/stat", consumes="application/json", produces="application/json")
+    public HttpResponseResult<MusicCompareVo.RecordStat> musicCompareRecordStatInfo(@RequestBody MusicCompareVo.StatQueryRequest request) {
+
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        MusicCompareWrapper.RecordStat records = musicCompareRecordStatService.findMusicCompareRecordStatInfo(sysUser.getId(),
+                MusicCompareWrapper.StatQueryInfo.from(request.jsonString()));
+
+        return succeed(MusicCompareVo.RecordStat.from(records.jsonString()));
+    }
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目统计信息查询", notes = "")
+    @PostMapping(value = "/record/page", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicCompareVo.RecordInfo>> musicCompareRecordPageInfo(@RequestBody MusicCompareVo.StatQueryRequest request) {
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 曲目统计信息
+        IPage<MusicCompareWrapper.RecordInfo> wrapper = musicCompareRecordStatService.findMusicCompareRecordPage(PageUtil.getPage(request),
+                MusicCompareWrapper.StatQueryInfo.from(request.jsonString()));
+
+        // 数据转换
+        List<MusicCompareVo.RecordInfo> pageInfos = JSON.parseArray(JSON.toJSONString(wrapper.getRecords()),
+                MusicCompareVo.RecordInfo.class);
+
+        return succeed(PageUtil.getPageInfo(wrapper, pageInfos));
+    }
+
+    /**
+     * 查询曲目统计汇总信息
+     */
+    @ApiOperation(value = "曲目评测信息查询")
+    @PostMapping(value = "/evaluate/page", consumes="application/json", produces="application/json")
+    public HttpResponseResult<PageInfo<MusicCompareWrapper.RecordEvaluate>> musicCompareEvaluatePageInfo(@RequestBody MusicCompareVo.EvaluateQueryInfo request) {
+
+        if (request.invalidParam()) {
+            return failed("无效的请求参数");
+        }
+
+        // 曲目统计信息
+        IPage<MusicCompareWrapper.RecordEvaluate> wrapper = musicCompareRecordStatService.findMusicCompareRecordEvaluatePage(PageUtil.getPage(request),
+                MusicCompareWrapper.EvaluteQueryInfo.from(request.jsonString()));
+
+        return succeed(PageUtil.pageInfo(wrapper));
+    }
+
+    /**
+     * 用户最近一次评测报告
+     * @param recordId 评测记录ID
+     * @return HttpResponseResult<Object>
+     */
+    @ApiOperation(value = "用户最后一次评测数据")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "recordId", value = "评测记录ID", required = true, dataType = "Integer")
+    })
+    @GetMapping("evaluate/report")
+    public HttpResponseResult<Object> getLastEvaluationMusicalNotesPlayStats(@RequestParam("recordId") Long recordId){
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if(sysUser == null){
+            throw new BizException("请登录");
+        }
+        return succeed(sysMusicCompareRecordService.getLastEvaluationMusicalNotesPlayStats(sysUser.getId(), recordId));
+    }
+}

+ 6 - 3
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/coupon/CouponInfoVO.java

@@ -49,10 +49,10 @@ public class CouponInfoVO {
         @ApiModelProperty("客户类型")
         private ClientEnum clientType;
 
-        @ApiModelProperty("优惠券类型")
+        @ApiModelProperty("优惠券类型 FULL_DISCOUNT(满减券) VOUCHER(代金券)")
         private CouponTypeEnum couponType;
 
-        @ApiModelProperty("可用品类")
+        @ApiModelProperty("可用品类 UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) ALBUM(专辑优惠券) SPARRING(陪练课购买券) LIVE(直播课购买券) ")
         private CouponCategoryEnum category;
 
         @ApiModelProperty("优惠券状态")
@@ -180,7 +180,10 @@ public class CouponInfoVO {
         @ApiModelProperty("客户端类型: TEACHER(老师端), STUDENT(学生端)")
         private ClientEnum clientType;
 
-        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) ")
+        @ApiModelProperty("可用品类: UNIVERSAL(全场通用) VIP(小酷Ai) " +
+                "PIANO(云酷琴房) MALL(商场购物券) MUSIC(单曲点播券) " +
+                "SPARRING(陪练课购买券) LIVE(直播课购买券) VIDEO(视频课购买券) " +
+                "VIDEO(视频课购买券)")
         private CouponCategoryEnum category;
 
         @ApiModelProperty("使用门槛")

+ 217 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/io/request/music/MusicCompareVo.java

@@ -0,0 +1,217 @@
+package com.yonge.cooleshow.admin.io.request.music;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.HeardLevelEnum;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.enums.music.MusicCompareType;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Created by Eric.Shang on 2022/10/17.
+ */
+public class MusicCompareVo implements Serializable {
+
+    /**
+     * 统计汇总查询条件
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @EqualsAndHashCode(callSuper = false)
+    public static class StatQueryRequest extends QueryInfo {
+
+        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("用户ID ")
+        private Long userId;
+
+        @ApiModelProperty("排序类型 TRAIN_DURATION(练习时长) TRAIN_FREQ(练习次数) EVALUATE_DURATION(评测时长) EVALUATE_FREQ(评测次数)")
+        private MusicCompareType compareType;
+
+        @ApiModelProperty("排序方式 升序(ASC) 降序(DESC)")
+        private String sortType;
+
+        @ApiModelProperty("曲目编号/名称")
+        private String keyword;
+
+        @ApiModelProperty("开始时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Long startTime;
+
+        @ApiModelProperty("结束时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Long endTime;
+
+        @ApiModelProperty(value = "曲目ID", hidden = true)
+        private Long musicId;
+        @ApiModelProperty(value = "曲目名称", hidden = true)
+        private String musicName;
+
+        public boolean invalidParam() {
+
+            return Objects.isNull(getClientType())
+                    || Objects.isNull(getUserId())
+                    || ClientEnum.invalid(getClientType().getCode());
+        }
+
+        public String jsonString() {
+
+            return JSON.toJSONString(this);
+        }
+
+        public MusicCompareType getCompareType() {
+            return Optional.ofNullable(compareType).orElse(MusicCompareType.EVALUATE_DURATION);
+        }
+
+        public String getSortType() {
+            return Optional.ofNullable(sortType).orElse("DESC");
+        }
+
+        public void setKeyword(String keyword) {
+            if (StringUtils.isNotEmpty(keyword)) {
+
+                if (keyword.matches(MK.EXP_INT)) {
+
+                    setMusicId(Long.parseLong(keyword));
+                } else {
+                    setMusicName(keyword);
+                }
+            }
+            this.keyword = keyword;
+        }
+
+        public StatQueryRequest userId(Long userId) {
+            this.userId = userId;
+            return this;
+        }
+
+    }
+
+    /**
+     * 曲目统计汇总信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordStat implements Serializable {
+
+        @ApiModelProperty("练习曲目总数")
+        private Long trainMusicNums;
+
+        @ApiModelProperty("使用时长")
+        private Long trainDuration;
+
+        @ApiModelProperty("使用次数")
+        private Long trainFrequency;
+
+        @ApiModelProperty("评测曲目总数")
+        private Long evaluateMusicNums;
+
+        @ApiModelProperty("评测时长")
+        private Long evaluateDuration;
+
+        @ApiModelProperty("评测次数")
+        private Long evaluateFrequency;
+
+        private List<RecordInfo> recordInfos;
+
+        public static RecordStat from(String record) {
+
+            return JSON.parseObject(record, RecordStat.class);
+        }
+    }
+
+    /**
+     * 曲目统计信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordInfo implements Serializable {
+
+        @ApiModelProperty("曲目ID")
+        private Long musicSheetId;
+
+        @ApiModelProperty("曲目名称")
+        private String musicName;
+
+        @ApiModelProperty("使用时长")
+        private Long trainDuration;
+
+        @ApiModelProperty("使用次数")
+        private Long trainFrequency;
+
+        @ApiModelProperty("评测时长")
+        private Long evaluateDuration;
+
+        @ApiModelProperty("评测次数")
+        private Long evaluateFrequency;
+
+        @ApiModelProperty("最近使用时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date recentTime;
+
+        @ApiModelProperty("作曲人")
+        private String composer;
+
+        @ApiModelProperty("音乐标签")
+        private String musicTagName;
+    }
+
+    /**
+     * 评测记录查询
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @EqualsAndHashCode(callSuper = false)
+    public static class EvaluateQueryInfo extends QueryInfo {
+
+        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("用户ID ")
+        private Long userId;
+
+        @ApiModelProperty("曲目ID ")
+        private Long musicId;
+
+        @ApiModelProperty("评测难度")
+        private HeardLevelEnum heardLevel;
+
+        @ApiModelProperty("开始时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Long startTime;
+
+        @ApiModelProperty("结束时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Long endTime;
+
+        public boolean invalidParam() {
+
+            return Objects.isNull(getClientType())
+                    || Objects.isNull(getUserId())
+                    || Objects.isNull(getMusicId());
+        }
+
+        public String jsonString() {
+
+            return JSON.toJSONString(this);
+        }
+    }
+}

+ 0 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicFavoriteDao.java

@@ -13,11 +13,4 @@ import org.apache.ibatis.annotations.Param;
  **/
 public interface MusicFavoriteDao extends BaseMapper<MusicFavorite> {
 
-    /**
-     * 曲目收藏数
-     *
-     * @param musicSheetId 曲目id
-     * @return
-     */
-    long selectMusicSheetFavoriteNum(@Param("musicSheetId") Long musicSheetId);
 }

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

@@ -7,6 +7,7 @@ import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -170,4 +171,9 @@ public interface MusicSheetDao extends BaseMapper<MusicSheet> {
      * @return List<StatGroupWrapper>
      */
     List<StatGroupWrapper> selectMusicAlbumStatInfo(@Param("musicIds") List<Long> musicIds);
+
+    /**
+     * 修改收藏数
+     */
+    void updateFavoriteCount(@Param("musicSheetId") Long musicSheetId, @Param("state") YesOrNoEnum state);
 }

+ 1 - 12
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/MusicTagDao.java

@@ -31,17 +31,6 @@ public interface MusicTagDao extends BaseMapper<MusicTag> {
 	List<MusicTagVo> selectPage(@Param("page") IPage page, @Param("param") MusicTagSearch musicTag);
 
 	/**
-	 * 根据父级id查询子级列表
-	 *
-	 * @param id        父级id
-	 * @param state     状态
-	 * @param idAndName 标签编号/名称
-	 * @return List
-	 */
-	List<MusicTagVo> getChildren(@Param("id") Long id, @Param("state") YesOrNoEnum state, @Param("idAndName") String idAndName);
-
-
-	/**
 	 * 根据父级id集合查询子集标签
 	 *
 	 * @param longList 父级id集合
@@ -65,5 +54,5 @@ public interface MusicTagDao extends BaseMapper<MusicTag> {
 	 * @param longs
 	 * @return
 	 */
-    Integer checkTagBeUsedMusicAblum(@Param("longs") List<Long> longs);
+    Integer checkTagBeUsedMusicAlbum(@Param("longs") List<Long> longs);
 }

+ 20 - 8
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/SysMusicCompareRecordDao.java

@@ -3,6 +3,8 @@ package com.yonge.cooleshow.biz.dal.dao;
 import java.util.List;
 import java.util.Map;
 
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import org.apache.ibatis.annotations.Param;
 
 import com.yonge.cooleshow.biz.dal.dto.StudentTrainChartDto;
@@ -23,24 +25,27 @@ public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareR
 	SysMusicCompareRecord getUserLastEvaluationData(@Param("userId") Long userId);
 
 	/**
+	 * @param userId   :
+	 * @param clientId
+	 * @return com.ym.mec.biz.dal.dto.StudentTrainOverviewDto
 	 * @describe 获取用户训练总览
 	 * @author Joburgess
 	 * @date 2021/8/11 0011
-	 * @param userId:
-	 * @return com.ym.mec.biz.dal.dto.StudentTrainOverviewDto
 	 */
-	StudentTrainOverviewDto getUserTrainOverView(@Param("userId") Long userId);
+	StudentTrainOverviewDto getUserTrainOverView(@Param("userId") Long userId, @Param("clientId") String clientId);
 
 	/**
+	 * @param userId    :
+	 * @param startTime :
+	 * @param endTime   :
+	 * @param clientId
+	 * @return java.util.List<com.ym.mec.biz.dal.dto.StudentTrainChartDto>
 	 * @describe 获取用户训练图表数据
 	 * @author Joburgess
 	 * @date 2021/8/12 0012
-	 * @param userId:
-	 * @param startTime:
-	 * @param endTime:
-	 * @return java.util.List<com.ym.mec.biz.dal.dto.StudentTrainChartDto>
 	 */
-	List<StudentTrainChartDto> getUserTrainChartData(@Param("userId") Long userId, @Param("startTime") String startTime, @Param("endTime") String endTime);
+	List<StudentTrainChartDto> getUserTrainChartData(@Param("userId") Long userId, @Param(
+			"startTime") String startTime, @Param("endTime") String endTime, @Param("clientId") String clientId);
 
 	int countMusicGroupStudentTrainData(Map<String, Object> params);
 
@@ -67,4 +72,11 @@ public interface SysMusicCompareRecordDao extends BaseDAO<Long, SysMusicCompareR
 	 * @return java.lang.Integer
 	 */
 	Integer getUserWeekMaxMusicScoreId(@Param("userId") Long userId, @Param("monday") String monday, @Param("heardLevel") HeardLevelEnum heardLevel);
+
+	/**
+	 * 曲目练习记录统计
+	 * @param queryInfo MusicCompareWrapper.RecordQueryInfo
+	 * @return List<StatGroupWrapper>
+	 */
+	List<StatGroupWrapper> selectMusicCompareRecordStatInfo(@Param("record") MusicCompareWrapper.RecordQueryInfo queryInfo);
 }

+ 51 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/AppMusicSheetVo.java

@@ -0,0 +1,51 @@
+package com.yonge.cooleshow.biz.dal.dto;
+
+import com.yonge.cooleshow.biz.dal.vo.MusicSheetVo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.util.List;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-10-18
+ */
+@ApiModel("app首页曲目信息")
+public class AppMusicSheetVo {
+
+    @ApiModelProperty("推荐曲目")
+    private List<MusicSheetVo> topMusicSheet;
+
+
+    @ApiModelProperty("最新曲目")
+    private List<MusicSheetVo> newMusicSheet;
+
+    @ApiModelProperty("最热曲目")
+    private List<MusicSheetVo> hotMusicSheet;
+
+    public List<MusicSheetVo> getHotMusicSheet() {
+        return hotMusicSheet;
+    }
+
+    public void setHotMusicSheet(List<MusicSheetVo> hotMusicSheet) {
+        this.hotMusicSheet = hotMusicSheet;
+    }
+
+    public List<MusicSheetVo> getTopMusicSheet() {
+        return topMusicSheet;
+    }
+
+    public void setTopMusicSheet(List<MusicSheetVo> topMusicSheet) {
+        this.topMusicSheet = topMusicSheet;
+    }
+
+    public List<MusicSheetVo> getNewMusicSheet() {
+        return newMusicSheet;
+    }
+
+    public void setNewMusicSheet(List<MusicSheetVo> newMusicSheet) {
+        this.newMusicSheet = newMusicSheet;
+    }
+}

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/MusicTagSaveDto.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.dto;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import io.swagger.annotations.ApiModelProperty;
 
 import javax.validation.constraints.NotBlank;
@@ -29,6 +30,30 @@ public class MusicTagSaveDto {
     @NotBlank(message = "标签名称不能为空")
     private String name;
 
+    @NotBlank(message = "标签类型不能为空")
+    @ApiModelProperty("标签类型 MUSIC:曲目 ALBUM:专辑")
+    private String type;
+
+
+    @ApiModelProperty("标签排序")
+    private Integer sortNumber = 0;
+
+    public Integer getSortNumber() {
+        return sortNumber;
+    }
+
+    public void setSortNumber(Integer sortNumber) {
+        this.sortNumber = sortNumber;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
     public Long getId() {
         return id;
     }

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

@@ -4,6 +4,7 @@ import com.yonge.cooleshow.biz.dal.enums.AccompanimentTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.AudioTypeEnum;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.ChargeTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.MusicSortType;
 import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.page.QueryInfo;
@@ -78,6 +79,17 @@ public class MusicSheetSearch  extends QueryInfo{
     @ApiModelProperty(value = "伴奏类型 HOMEMODE:自制伴奏  COMMON:普通伴奏")
     private AccompanimentTypeEnum accompanimentType;
 
+    @ApiModelProperty("TOP:推荐曲目 NEW:最新曲目 HOT:最热曲目")
+    private MusicSortType musicSortType;
+
+    public MusicSortType getMusicSortType() {
+        return musicSortType;
+    }
+
+    public void setMusicSortType(MusicSortType musicSortType) {
+        this.musicSortType = musicSortType;
+    }
+
     public AudioTypeEnum getAudioType() {
         return audioType;
     }

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

@@ -19,6 +19,17 @@ public class MusicTagSearch extends QueryInfo{
 	@ApiModelProperty("标签状态(0:禁用,1:启用)")
 	private YesOrNoEnum state;
 
+	@ApiModelProperty("标签类型 MUSIC:曲目 ALBUM:专辑")
+	private String type;
+
+	public String getType() {
+		return type;
+	}
+
+	public void setType(String type) {
+		this.type = type;
+	}
+
 	public String getIdAndName() {
 		return idAndName;
 	}

+ 73 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicCompareRecordStat.java

@@ -0,0 +1,73 @@
+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 java.io.Serializable;
+import java.util.Date;
+
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 曲目练习统计表
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+@Getter
+@Setter
+@TableName("music_compare_record_stat")
+@ApiModel(value = "MusicCompareRecordStat对象", description = "曲目练习统计表")
+public class MusicCompareRecordStat implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("主键ID")
+    @TableId(value = "id_", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("曲目编号")
+    @TableField("music_sheet_id_")
+    private Long musicSheetId;
+
+    @ApiModelProperty("客户端标识")
+    @TableField("client_id_")
+    private ClientEnum clientId;
+
+    @ApiModelProperty("用户编号")
+    @TableField("user_id_")
+    private Long userId;
+
+    @ApiModelProperty("使用时长")
+    @TableField("train_duration_")
+    private Long trainDuration;
+
+    @ApiModelProperty("使用次数")
+    @TableField("train_frequency_")
+    private Long trainFrequency;
+
+    @ApiModelProperty("评测时长")
+    @TableField("evaluate_duration_")
+    private Long evaluateDuration;
+
+    @ApiModelProperty("评测次数")
+    @TableField("evaluate_frequency_")
+    private Long evaluateFrequency;
+
+    @ApiModelProperty("最近使用时间")
+    @TableField("recent_time_")
+    private Long recentTime;
+
+    @ApiModelProperty("创建时间")
+    @TableField("create_time_")
+    private Date createTime;
+
+
+}

+ 25 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheet.java

@@ -84,6 +84,11 @@ public class MusicSheet implements Serializable {
 	@ApiModelProperty(value = "mp3类型 MP3:mp3, MP3_METRONOME:MP3_METRONOME,")
 	private AudioTypeEnum mp3Type;
 
+
+	@TableField("favorite_count_")
+	@ApiModelProperty(value = "收藏数")
+	private Integer favoriteCount;
+
     @NotBlank(message = "曲谱标签不能为空!")
     @TableField("music_tag_")
     @ApiModelProperty(value = "曲谱标签(多个标签用逗号分隔)")
@@ -134,6 +139,10 @@ public class MusicSheet implements Serializable {
 	@ApiModelProperty(value = "提交审核时间")
 	private Date submitAuditTime;
 
+	@TableField("first_pass_audit_time_")
+	@ApiModelProperty(value = "第一次通过审核时间")
+	private Date firstPassAuditTime;
+
     @TableField("sort_number_")
     @ApiModelProperty(value = "排序号")
     private Integer sortNumber;  //排序号
@@ -216,6 +225,22 @@ public class MusicSheet implements Serializable {
 	@ApiModelProperty(value = "假删除标识 0:未删除 1:已删除")
 	private Boolean delFlag;
 
+	public Date getFirstPassAuditTime() {
+		return firstPassAuditTime;
+	}
+
+	public void setFirstPassAuditTime(Date firstPassAuditTime) {
+		this.firstPassAuditTime = firstPassAuditTime;
+	}
+
+	public Integer getFavoriteCount() {
+		return favoriteCount;
+	}
+
+	public void setFavoriteCount(Integer favoriteCount) {
+		this.favoriteCount = favoriteCount;
+	}
+
 	public String getMusicImg() {
 		return musicImg;
 	}

+ 26 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicTag.java

@@ -35,6 +35,15 @@ public class MusicTag implements Serializable {
     @ApiModelProperty(value = "标签状态(0:禁用,1:启用)")
     private YesOrNoEnum state;
 
+    @TableField(value = "type_")
+    @ApiModelProperty("标签类型 MUSIC:曲目 ALBUM:专辑")
+    private String type;
+
+
+    @TableField(value = "sort_number_")
+    @ApiModelProperty("标签排序")
+    private Integer sortNumber;
+
 	@TableField(value = "del_flag_")
     @ApiModelProperty(value = "假删标识(0:正常,1:删除)")
     private Boolean delFlag= false;
@@ -59,7 +68,23 @@ public class MusicTag implements Serializable {
     @ApiModelProperty(value = "更新人(后台平台用户)")
     private Long updateBy;  //更新人(老师或者是后台平台用户)
 
-	public Long getId() {
+    public Integer getSortNumber() {
+        return sortNumber;
+    }
+
+    public void setSortNumber(Integer sortNumber) {
+        this.sortNumber = sortNumber;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public Long getId() {
         return id;
     }
 

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

@@ -1,11 +1,13 @@
 package com.yonge.cooleshow.biz.dal.enums;
 
+import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.yonge.toolset.base.enums.BaseEnum;
 
 public enum FeatureType implements BaseEnum<String, FeatureType> {
     CLOUD_STUDY_TRAIN("小酷Ai训练"),
     CLOUD_STUDY_EVALUATION("小酷Ai评测");
 
+    @EnumValue
     private String code;
 
     private String desc;

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

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.enums;
 
+import com.baomidou.mybatisplus.annotation.EnumValue;
 import com.yonge.toolset.base.enums.BaseEnum;
 
 public enum HeardLevelEnum implements BaseEnum<String, HeardLevelEnum> {
@@ -7,6 +8,7 @@ public enum HeardLevelEnum implements BaseEnum<String, HeardLevelEnum> {
     ADVANCED("进阶级", 1, 0.9f, 1.3f),
     PERFORMER("大师级", 3, 0.93f, 1.1f);
 
+    @EnumValue
     private String code;
 
     private String msg;

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

@@ -0,0 +1,37 @@
+package com.yonge.cooleshow.biz.dal.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-10-18
+ */
+public enum MusicSortType implements BaseEnum<String, MusicSheetType> {
+
+    TOP("推荐曲目"), // 置顶 曲目排序值展示
+    HOT("最热曲目"), // 首次通过审核时间倒序展示
+    NEW("最新曲目"); // 乐谱收藏数量倒序展示
+
+    @EnumValue
+    private String code;
+
+    private String msg;
+
+    MusicSortType(String msg) {
+        this.msg = msg;
+        this.code = this.name();
+    }
+
+    @Override
+    public String getCode() {
+        return this.code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+}

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

@@ -19,6 +19,7 @@ public enum CouponCategoryEnum implements BaseEnum<String, CouponCategoryEnum> {
     PIANO("云酷琴房", "PINAO_ROOM"),
     MALL("商场购物券", "MALL"),
     MUSIC("单曲点播券", "MUSIC"),
+    ALBUM("专辑优惠券", "ALBUM"),
     SPARRING("陪练课购买券", "PRACTICE"),
     LIVE("直播课购买券", "LIVE"),
     VIDEO("视频课购买券", "VIDEO"),

+ 59 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/enums/music/MusicCompareType.java

@@ -0,0 +1,59 @@
+package com.yonge.cooleshow.biz.dal.enums.music;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.yonge.toolset.base.enums.BaseEnum;
+
+/**
+ * 曲目统计排序类型
+ *
+ * @author liujunchi
+ * @date 2022-04-28
+ */
+public enum MusicCompareType implements BaseEnum<String, MusicCompareType> {
+    TRAIN_DURATION("练习时长", "train_duration_"),
+    TRAIN_FREQ("练习次数", "train_frequency_"),
+    EVALUATE_DURATION("评测时长", "evaluate_duration_"),
+    EVALUATE_FREQ("评测次数", "evaluate_frequency_"),
+    ;
+    @EnumValue
+    private String code;
+    private String msg;
+    private String sortField;
+
+    MusicCompareType(String msg, String field) {
+        this.code = this.name();
+        this.msg = msg;
+        this.sortField = field;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public String getSortField() {
+        return sortField;
+    }
+
+    /**
+     * 校验类型合法性
+     * @param clientType 客户端类型
+     * @return boolean
+     */
+    public static boolean invalid(String clientType) {
+
+        MusicCompareType[] values = MusicCompareType.values();
+
+        for (MusicCompareType item : values) {
+
+            if (item.getCode().equals(clientType)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}

+ 45 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/mapper/MusicCompareRecordStatMapper.java

@@ -0,0 +1,45 @@
+package com.yonge.cooleshow.biz.dal.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.MusicCompareRecordStat;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 曲目练习统计表 Mapper 接口
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+public interface MusicCompareRecordStatMapper extends BaseMapper<MusicCompareRecordStat> {
+
+    /**
+     * 用户曲目统计查询
+     * @param page IPage<MusicCompareWrapper.RecordInfo>
+     * @param query MusicCompareWrapper.StatQueryInfo
+     * @return List<MusicCompareWrapper.RecordInfo>
+     */
+    List<MusicCompareWrapper.RecordInfo> selectMusicCompareRecordPage(@Param("page") IPage<MusicCompareWrapper.RecordInfo> page, @Param("record") MusicCompareWrapper.StatQueryInfo query);
+
+    /**
+     * 用户曲目统计汇总
+     * @param query MusicCompareWrapper.StatQueryInfo
+     * @return List<StatGroupWrapper>
+     */
+    List<StatGroupWrapper> selectMusicCompareRecordStatInfo(@Param("record") MusicCompareWrapper.StatQueryInfo query);
+
+    /**
+     * 曲目练习评测记录
+     * @param page IPage<MusicCompareWrapper.RecordEvaluate>
+     * @param query MusicCompareWrapper.EvaluteQueryInfo
+     * @return List<MusicCompareWrapper.RecordEvaluate>
+     */
+    List<MusicCompareWrapper.RecordEvaluate> selectMusicCompareEvaluatePage(@Param("page") IPage<MusicCompareWrapper.RecordEvaluate> page,
+                                                                            @Param("record") MusicCompareWrapper.EvaluteQueryInfo query);
+}

+ 10 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/queryInfo/SysMusicCompareRecordQueryInfo.java

@@ -35,6 +35,16 @@ public class SysMusicCompareRecordQueryInfo extends QueryInfo {
 
     private Integer organId;
 
+    private String clientId;
+
+    public String getClientId() {
+        return clientId;
+    }
+
+    public void setClientId(String clientId) {
+        this.clientId = clientId;
+    }
+
     public Integer getOrganId() {
         return organId;
     }

+ 49 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicCompareRecordStatService.java

@@ -0,0 +1,49 @@
+package com.yonge.cooleshow.biz.dal.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.MusicCompareRecordStat;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 曲目练习统计表 服务类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+public interface MusicCompareRecordStatService extends IService<MusicCompareRecordStat> {
+
+    /**
+     * 曲目统计汇总信息
+     * @param sysUserId 用户ID
+     * @param info MusicCompareWrapper.StatQueryInfo
+     * @return MusicCompareWrapper.RecordStat
+     */
+    MusicCompareWrapper.RecordStat findMusicCompareRecordStatInfo(Long sysUserId, MusicCompareWrapper.StatQueryInfo info);
+
+    /**
+     * 曲目统计信息查询
+     * @param page IPage<MusicCompareWrapper.RecordInfo>
+     * @param query MusicCompareWrapper.StatQueryInfo
+     * @return IPage<MusicCompareWrapper.RecordInfo>
+     */
+    IPage<MusicCompareWrapper.RecordInfo> findMusicCompareRecordPage(IPage<MusicCompareWrapper.RecordInfo> page, MusicCompareWrapper.StatQueryInfo query);
+
+    /**
+     * 批量更新曲目统计汇总
+     * @param recordInfos List<MusicCompareWrapper.RecordInfo>
+     */
+    void batchUpdateMusicCompareRecordStat(List<MusicCompareWrapper.RecordInfo> recordInfos);
+
+    /**
+     * 曲目评测记录查询
+     * @param page MusicCompareWrapper.RecordEvaluate
+     * @param query MusicCompareWrapper.EvaluteQueryInfo
+     * @return IPage<MusicCompareWrapper.RecordEvaluate>
+     */
+    IPage<MusicCompareWrapper.RecordEvaluate> findMusicCompareRecordEvaluatePage(IPage<MusicCompareWrapper.RecordEvaluate> page, MusicCompareWrapper.EvaluteQueryInfo query);
+}

+ 6 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicFavoriteService.java

@@ -3,6 +3,7 @@ package com.yonge.cooleshow.biz.dal.service;
 import com.yonge.cooleshow.biz.dal.entity.MusicFavorite;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 
 import java.util.List;
 
@@ -24,11 +25,13 @@ public interface MusicFavoriteService extends IService<MusicFavorite> {
      */
     List<MusicFavorite> getFavorite(Long userId, Long musicSheetId, ClientEnum clientType);
 
+
     /**
-     * 获取曲目收藏数量
+     * 检查是否收藏曲目
      *
      * @param musicSheetId 曲目id
-     * @return
+     * @param userId 用户id
+     * @param userType 用户类型 老师 学生
      */
-    long getMusicSheetFavoriteNum(Long musicSheetId);
+    YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType);
 }

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

@@ -64,8 +64,9 @@ public interface MusicTagService extends IService<MusicTag>  {
 	 * 获取标签树
 	 *
 	 * @return list
+	 * @param type
 	 */
-    List<MusicTagVo> selectMusicTagTree();
+    List<MusicTagVo> selectMusicTagTree(String type);
 
 	/**
 	 * 检查每个二级标签都在不同的一级标签下

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

@@ -0,0 +1,229 @@
+package com.yonge.cooleshow.biz.dal.service.impl;
+
+import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.biz.dal.entity.MusicCompareRecordStat;
+import com.yonge.cooleshow.biz.dal.entity.MusicTag;
+import com.yonge.cooleshow.biz.dal.entity.SysMusicCompareRecord;
+import com.yonge.cooleshow.biz.dal.enums.EQueryOp;
+import com.yonge.cooleshow.biz.dal.enums.FeatureType;
+import com.yonge.cooleshow.biz.dal.mapper.MusicCompareRecordStatMapper;
+import com.yonge.cooleshow.biz.dal.service.MusicCompareRecordStatService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.biz.dal.service.MusicTagService;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 曲目练习统计表 服务实现类
+ * </p>
+ *
+ * @author Eric
+ * @since 2022-10-17
+ */
+@Service
+public class MusicCompareRecordStatServiceImp extends ServiceImpl<MusicCompareRecordStatMapper, MusicCompareRecordStat> implements MusicCompareRecordStatService {
+
+    @Autowired
+    private MusicTagService musicTagService;
+
+    /**
+     * 曲目统计汇总信息
+     *
+     * @param sysUserId 用户ID
+     * @param info      MusicCompareWrapper.StatQueryInfo
+     * @return MusicCompareWrapper.RecordStat
+     */
+    @Override
+    public MusicCompareWrapper.RecordStat findMusicCompareRecordStatInfo(Long sysUserId, MusicCompareWrapper.StatQueryInfo info) {
+
+        // 统计汇总信息
+        MusicCompareWrapper.RecordStat wrapper = MusicCompareWrapper.RecordStat.builder()
+                .trainMusicNums(0L)
+                .trainDuration(0L)
+                .trainFrequency(0L)
+                .evaluateMusicNums(0L)
+                .evaluateDuration(0L)
+                .evaluateFrequency(0L)
+                .recordInfos(Lists.newArrayList())
+                .build();
+
+        // 指标统计信息
+        Lists.newArrayList(EQueryOp.values()).parallelStream().forEach(dataType -> {
+
+
+            MusicCompareWrapper.StatQueryInfo queryInfo = JSON.parseObject(info.jsonString(), MusicCompareWrapper.StatQueryInfo.class);
+
+            switch (dataType) {
+                case FUNCTION_1: // 练习曲目
+                    {
+                        List<StatGroupWrapper> groupWrappers = getBaseMapper().selectMusicCompareRecordStatInfo(queryInfo.trainMusic(true));
+
+                        if (CollectionUtils.isNotEmpty(groupWrappers)) {
+
+                            StatGroupWrapper groupWrapper = groupWrappers.get(0);
+
+                            wrapper.trainMusicNums(groupWrapper.getMusicNum())
+                                    .trainDuration(groupWrapper.getDurationNum() / 60)
+                                    .trainFrequency(groupWrapper.getFrequencyNum());
+                        }
+                    }
+                    break;
+                case FUNCTION_2: // 评测曲目
+                    {
+                        List<StatGroupWrapper> groupWrappers = getBaseMapper().selectMusicCompareRecordStatInfo(queryInfo.evaluateMusic(true));
+
+                        if (CollectionUtils.isNotEmpty(groupWrappers)) {
+
+                            StatGroupWrapper groupWrapper = groupWrappers.get(0);
+
+                            wrapper.evaluateMusicNums(groupWrapper.getMusicNum())
+                                    .evaluateDuration(groupWrapper.getDurationNum() / 60)
+                                    .evaluateFrequency(groupWrapper.getFrequencyNum());
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        });
+
+        // 曲目统计信息
+        IPage<MusicCompareWrapper.RecordInfo> page = findMusicCompareRecordPage(PageUtil.getPage(info), info);
+        if (Objects.nonNull(page)) {
+
+            wrapper.setRecordInfos(page.getRecords());
+        }
+
+        return wrapper;
+    }
+
+    /**
+     * 曲目统计信息查询
+     *
+     * @param page  IPage<MusicCompareWrapper.RecordInfo>
+     * @param query MusicCompareWrapper.StatQueryInfo
+     * @return IPage<MusicCompareWrapper.RecordInfo>
+     */
+    @Override
+    public IPage<MusicCompareWrapper.RecordInfo> findMusicCompareRecordPage(IPage<MusicCompareWrapper.RecordInfo> page, MusicCompareWrapper.StatQueryInfo query) {
+
+        // 用户曲目统计信息
+        List<MusicCompareWrapper.RecordInfo> recordInfos = getBaseMapper().selectMusicCompareRecordPage(page, query);
+
+        if (CollectionUtils.isNotEmpty(recordInfos)) {
+
+            List<String> collect = recordInfos.stream()
+                    .filter(x -> StringUtils.isNotEmpty(x.getMusicTag()))
+                    .flatMap(x -> Arrays.stream(x.getMusicTag().split(",")))
+                    .distinct().collect(Collectors.toList());
+
+            Map<Long, String> tagNameMap = musicTagService.lambdaQuery()
+                    .eq(MusicTag::getType, "MUSIC")
+                    .in(MusicTag::getId, collect)
+                    .list().stream()
+                    .collect(Collectors.toMap(MusicTag::getId, MusicTag::getName, (o, n) -> n));
+
+            String tagName;
+            for (MusicCompareWrapper.RecordInfo item : recordInfos) {
+
+                if (StringUtils.isNotEmpty(item.getMusicTag())) {
+
+                    List<Long> tagIds = Arrays.stream(item.getMusicTag().split(","))
+                            .map(Long::parseLong).distinct().collect(Collectors.toList());
+
+                    tagName = tagNameMap.entrySet().stream()
+                            .filter(x -> tagIds.contains(x.getKey()))
+                            .map(Map.Entry::getValue).collect(Collectors.joining(","));
+
+                    item.setMusicTagName(tagName);
+                }
+
+                // 设置练习时长,评测时长
+                item.trainDuration(item.getTrainDuration() / 60)
+                        .evaluateDuration(item.getEvaluateDuration() / 60);
+            }
+        }
+
+        return page.setRecords(recordInfos);
+    }
+
+    /**
+     * 批量更新曲目统计汇总
+     *
+     * @param recordInfos List<MusicCompareWrapper.RecordInfo>
+     */
+    @Override
+    public void batchUpdateMusicCompareRecordStat(List<MusicCompareWrapper.RecordInfo> recordInfos) {
+
+        for (MusicCompareWrapper.RecordInfo record : recordInfos) {
+
+            // 判断曲目统计消息是新增还是更新
+            MusicCompareRecordStat musicRecord = lambdaQuery()
+                    .eq(MusicCompareRecordStat::getMusicSheetId, record.getMusicSheetId())
+                    .eq(MusicCompareRecordStat::getUserId, record.getUserId())
+                    .eq(MusicCompareRecordStat::getClientId, record.getClientId())
+                    .one();
+
+            if (Objects.isNull(musicRecord)) {
+
+                // 初始化数据默认值
+                if (Objects.isNull(record.getTrainDuration())) {
+                    record.setTrainDuration(0L);
+                }
+                if (Objects.isNull(record.getTrainFrequency())) {
+                    record.setTrainFrequency(0L);
+                }
+                if (Objects.isNull(record.getEvaluateDuration())) {
+                    record.setEvaluateDuration(0L);
+                }
+                if (Objects.isNull(record.getEvaluateFrequency())) {
+                    record.setEvaluateFrequency(0L);
+                }
+
+                // 新增记录
+                save(JSON.parseObject(record.jsonString(), MusicCompareRecordStat.class));
+            } else {
+                record.setId(musicRecord.getId());
+                // 更新记录
+                updateById(JSON.parseObject(record.jsonString(), MusicCompareRecordStat.class));
+            }
+        }
+    }
+
+    /**
+     * 曲目评测记录查询
+     *
+     * @param page  MusicCompareWrapper.RecordEvaluate
+     * @param query MusicCompareWrapper.EvaluteQueryInfo
+     * @return IPage<MusicCompareWrapper.RecordEvaluate>
+     */
+    @Override
+    public IPage<MusicCompareWrapper.RecordEvaluate> findMusicCompareRecordEvaluatePage(IPage<MusicCompareWrapper.RecordEvaluate> page,
+                                                                                        MusicCompareWrapper.EvaluteQueryInfo query) {
+        if (FeatureType.CLOUD_STUDY_EVALUATION == query.getFeature()) {
+
+            // 只查询生成评测试报告数据
+            query.setScoreData(true);
+        }
+        // 分页查询条件
+        List<MusicCompareWrapper.RecordEvaluate> evaluates = getBaseMapper().selectMusicCompareEvaluatePage(page, query);
+
+        return page.setRecords(evaluates);
+    }
+}

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

@@ -5,6 +5,7 @@ import com.yonge.cooleshow.biz.dal.entity.MusicFavorite;
 import com.yonge.cooleshow.biz.dal.dao.MusicFavoriteDao;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.MusicFavoriteService;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
@@ -41,9 +42,14 @@ public class MusicFavoriteServiceImpl extends ServiceImpl<MusicFavoriteDao,Music
 
     }
 
+
     @Override
-    public long getMusicSheetFavoriteNum(Long musicSheetId) {
-        return  baseMapper.selectMusicSheetFavoriteNum(musicSheetId);
+    public YesOrNoEnum checkFavorite(Long musicSheetId, Long userId, ClientEnum userType) {
+        return this.lambdaQuery()
+                .eq(MusicFavorite::getUserId,userId)
+                .eq(MusicFavorite::getMusicSheetId,musicSheetId)
+                .eq(MusicFavorite::getClientType,userType)
+                .count() >0?YesOrNoEnum.YES:YesOrNoEnum.NO;
 
     }
 }

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

@@ -116,6 +116,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
     @Autowired
     private TeacherService teacherService;
 
+
     @Autowired
     private StudentStarService studentStarService;
     @Autowired
@@ -267,6 +268,12 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         if (sysUser == null) {
             return detail;
         }
+
+        // 收藏
+        YesOrNoEnum favorite = musicFavoriteService.checkFavorite(id,sysUser.getId(),userType);
+        detail.setFavorite(favorite);
+
+        // 播放状态
         if (AuthStatusEnum.UNPASS.getCode().equals(detail.getAuditStatus().getCode())) {
             String reason = musicSheetAuthRecordService.selectAuditReason(id);
             detail.setReason(reason);
@@ -284,10 +291,6 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         } else {
             detail.setPlay(YesOrNoEnum.YES);
         }
-        if (ClientEnum.STUDENT.getCode().equals(userType.getCode())) {
-            // 学生进入小酷Ai练习,添加一条练习记录
-            musicSheetPracticeRecordService.addRecord(id, sysUser.getId());
-        }
         return detail;
     }
 
@@ -386,21 +389,8 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         		records = baseMapper.selectStudentMusicPage(page, query);
         	}
     	}*/
-    	
-        IPage<MusicSheetVo> musicSheetVoIPage = page.setRecords(records);
-        if (query.getStudentId() != null) {
-            StudentVo studentVo = studentService.detail(query.getStudentId());
-            if (studentVo == null) {
-                return musicSheetVoIPage;
-            }
-            for (MusicSheetVo record : records) {
-                if (ChargeTypeEnum.VIP.getCode().equals(record.getChargeType().getCode())
-                        && YesOrNoEnum.YES.getCode().equals(studentVo.getIsVip().getCode())) {
-                    record.setPlay(YesOrNoEnum.YES);
-                }
-            }
-        }
-        return musicSheetVoIPage;
+
+        return page.setRecords(records);
 
     }
 
@@ -434,9 +424,11 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             musicFavorite.setClientType(clientType);
             musicFavorite.setUserId(userId);
             musicFavorite.setFavoriteTime(new Date());
+            musicSheetDao.updateFavoriteCount(musicSheetId,YesOrNoEnum.YES);
             return musicFavoriteService.save(musicFavorite);
         } else {
             List<Long> ids = musicFavorites.stream().map(MusicFavorite::getId).collect(Collectors.toList());
+            musicSheetDao.updateFavoriteCount(musicSheetId,YesOrNoEnum.NO);
             return musicFavoriteService.removeByIds(ids);
         }
     }
@@ -529,11 +521,11 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         boolean flag;
         Long originalMusicSheetId = musicSheetAuthRecordService.audit(param, userId);
         musicSheet.setAuditStatus(param.getAuthStatus());
-            if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && StringUtil.isEmpty(param.getMusicImg())) {
-                throw new BizException("曲目渲染失败");
-            } else if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && !StringUtil.isEmpty(param.getMusicImg())) {
-                musicSheet.setMusicImg(param.getMusicImg());
-            }
+        if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && StringUtil.isEmpty(param.getMusicImg())) {
+            throw new BizException("曲目渲染失败");
+        } else if (param.getAuthStatus().equals(AuthStatusEnum.PASS) && !StringUtil.isEmpty(param.getMusicImg())) {
+            musicSheet.setMusicImg(param.getMusicImg());
+        }
         musicSheet.setUpdateBy(userId);
         musicSheet.setUpdateTime(new Date());
         if (AuthStatusEnum.PASS.getCode().equals(param.getAuthStatus().getCode())) {
@@ -554,6 +546,8 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             // 修改老师标签
             teacherService.setTeacherTag(musicSheet.getUserId(), TeacherTagEnum.MUSIC);
 
+            // 设置首次通过审核时间
+            musicSheet.setFirstPassAuditTime(new Date());
         }
         flag = this.updateById(musicSheet);
 
@@ -588,12 +582,17 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                                                                                                               .peek(musicSheetAccompaniment -> musicSheetAccompaniment.setMusicSheetId(
                                                                                                                       musicSheet.getId()))
                                                                                                               .collect(Collectors.toList());
+
+            if (originalMusicSheet.getFirstPassAuditTime() != null) {
+                musicSheet.setFirstPassAuditTime(originalMusicSheet.getFirstPassAuditTime());
+            }
             musicSheetAccompanimentList.addAll(originalMusicSheetAccompanimentList);
             if (CollectionUtils.isEmpty(musicSheetAccompanimentList)) {
                 return;
             }
             musicSheetAccompanimentService.saveOrUpdateBatch(musicSheetAccompanimentList);
             musicSheet.setId(originalMusicSheetId);
+            musicSheet.setFavoriteCount(originalMusicSheet.getFavoriteCount());
         }
     }
 
@@ -636,6 +635,10 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
     @Transactional(rollbackFor = Exception.class)
     public boolean saveMusicSheet(MusicSheetDto musicSheetDto, Long userId) {
 
+        String[] split = musicSheetDto.getMusicTag().split(",");
+        if (split.length >3) {
+            throw new BizException("曲目标签数不能超过3个");
+        }
         MusicSheet oldMusicSheet = null;
         Long originalMusicSheetId = null;
         Long lastMusicSheetId = musicSheetDto.getId();
@@ -1025,7 +1028,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         List<ErrMsg> errMsgList = new ArrayList<>();
         dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
         List<MusicSheetDto> musicSheetDtoList = new ArrayList<>();
-        List<MusicTagVo> musicTagVoList = musicTagService.selectMusicTagTree();
+        List<MusicTagVo> musicTagVoList = musicTagService.selectMusicTagTree("MUSIC");
         List<Subject> subjects = subjectService.subjectSelect(null, null);
         Date date = new Date();
         for (ExcelDataReaderProperty<MusicSheetExport> readerProperty : dataList) {
@@ -1138,10 +1141,6 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         MusicSheetWebsiteDetailVo musicSheetWebsiteDetailVo = new MusicSheetWebsiteDetailVo();
         BeanUtils.copyProperties(detail, musicSheetWebsiteDetailVo);
 
-        // 曲目收藏数
-        long musicSheetFavoriteNum = musicFavoriteService.getMusicSheetFavoriteNum(musicSheetId);
-        musicSheetWebsiteDetailVo.setFavoriteNum(musicSheetFavoriteNum);
-
         // 老师信息
         TeacherVo teacherVo = teacherService.detail(detail.getUserId());
         TeacherMusicSheetListVo teacherMusicSheetListVo = new TeacherMusicSheetListVo();
@@ -1171,6 +1170,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
                 musicSheetWebsiteDetailVo.setFavorite(YesOrNoEnum.YES);
             }
         }
+        musicSheetWebsiteDetailVo.setFavoriteNum(Long.valueOf(detail.getFavoriteCount()));
 
         // 老师的曲目
         MusicSheetSearch musicSheetSearch = new MusicSheetSearch();
@@ -1213,13 +1213,13 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
         MusicSheetDetailVo musicSheet = detail(musicSheetId, null, null);
 
         YesOrNoEnum discount = YesOrNoEnum.NO;
-        if (ChargeTypeEnum.VIP.equals(musicSheet.getChargeType())) {
+        if (musicSheet.getPaymentType().contains(ChargeTypeEnum.VIP.getCode())) {
             ActivityPlanVo activityPlanVo = activityPlanService.activityShare(ActivityShareEnum.VIP, sysUser.getId());
             if (activityPlanVo != null) {
                 result.setActivityId(activityPlanVo.getId());
                 discount = YesOrNoEnum.YES;
             }
-        } else if (ChargeTypeEnum.CHARGE.equals(musicSheet.getChargeType())) {
+        } else if (musicSheet.getPaymentType().contains(ChargeTypeEnum.CHARGE.getCode())) {
             ActivityPlanVo activityPlanVo = activityPlanService.activityShare(ActivityShareEnum.MUSIC_SHEET,
                                                                               sysUser.getId());
             if (activityPlanVo != null) {
@@ -1251,18 +1251,19 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao, MusicSheet
             return this.saveOrUpdate(musicSheet);
         }
         String subjectIdsStr = musicSheet.getMusicSubject();
-        
-		for (String subjectId : subjectIdsStr.split(",")) {
-			Integer count = this.lambdaQuery().eq(MusicSheet::getDelFlag, YesOrNoEnum.NO).eq(MusicSheet::getTopFlag, YesOrNoEnum.YES)
-					.eq(MusicSheet::getState, YesOrNoEnum.YES).apply(!subjectId.isEmpty(), "FIND_IN_SET ('" + subjectId + "',music_subject_)").count();
-            String topNum = sysConfigService.findConfigValue(SysConfigConstant.MUSIC_SHEET_TOP_NUM);
-            if (StringUtil.isEmpty(topNum)) {
-                throw new BizException("获取置顶配置失败");
-            }
-            if (count >= Integer.parseInt(topNum)) {
-				throw new BizException("首页推荐数量达到[" +topNum+"]上限,请先取消其他曲谱推荐");
-			}
-		}
+
+        // 置顶不做限制
+		// for (String subjectId : subjectIdsStr.split(",")) {
+		// 	Integer count = this.lambdaQuery().eq(MusicSheet::getDelFlag, YesOrNoEnum.NO).eq(MusicSheet::getTopFlag, YesOrNoEnum.YES)
+		// 			.eq(MusicSheet::getState, YesOrNoEnum.YES).apply(!subjectId.isEmpty(), "FIND_IN_SET ('" + subjectId + "',music_subject_)").count();
+        //     String topNum = sysConfigService.findConfigValue(SysConfigConstant.MUSIC_SHEET_TOP_NUM);
+        //     if (StringUtil.isEmpty(topNum)) {
+        //         throw new BizException("获取置顶配置失败");
+        //     }
+        //     if (count >= Integer.parseInt(topNum)) {
+		// 		throw new BizException("首页推荐数量达到[" +topNum+"]上限,请先取消其他曲谱推荐");
+		// 	}
+		// }
         musicSheet.setTopFlag(YesOrNoEnum.YES);
         return this.saveOrUpdate(musicSheet);
     }

+ 41 - 83
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicTagServiceImpl.java

@@ -9,7 +9,6 @@ import com.yonge.cooleshow.biz.dal.dao.MusicTagDao;
 import com.yonge.cooleshow.biz.dal.dto.MusicTagSaveDto;
 import com.yonge.cooleshow.biz.dal.dto.search.MusicTagSearch;
 import com.yonge.cooleshow.biz.dal.entity.MusicTag;
-import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
 import com.yonge.cooleshow.biz.dal.service.MusicTagService;
 import com.yonge.cooleshow.biz.dal.vo.MusicTagVo;
 import com.yonge.cooleshow.common.enums.YesOrNoEnum;
@@ -35,15 +34,13 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
-    private MusicSheetService musicSheetService;
-
 	@Override
     public MusicTagVo detail(Long id) {
         return baseMapper.detail(id);
     }
 
      @Override
-    public IPage<MusicTagVo> selectPage(IPage<MusicTagVo> page, MusicTagSearch query){
+     public IPage<MusicTagVo> selectPage(IPage<MusicTagVo> page, MusicTagSearch query){
          IPage<MusicTagVo> musicTagVoIPage = page.setRecords(baseMapper.selectPage(page, query));
          // 将父类的id 拿出来,集体查出子集
          List<Long> longList = musicTagVoIPage
@@ -56,34 +53,22 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
 
          // 根据父级id, 将子集分类
          Map<String, List<MusicTagVo>> musicTagMap = musicTagVoList.stream()
-                                                                .collect(Collectors.groupingBy( vo -> vo.getParentTagId().toString()));
+                                                                   .collect(Collectors.groupingBy( vo -> vo.getId().toString()));
          musicTagVoIPage.getRecords()
-                 .forEach(musicTagVo -> {
-                     List<MusicTagVo> childrenList = musicTagMap.get(musicTagVo.getId().toString());
-                     if (CollectionUtils.isEmpty(childrenList)) {
-                         return;
-                     }
-                     childrenList.forEach(children -> {
-                         musicTagVo.setEnablePlatformMusicSheetNum(musicTagVo.getEnablePlatformMusicSheetNum() + children.getEnablePlatformMusicSheetNum());
-                         musicTagVo.setEnableTeacherMusicSheetNum(musicTagVo.getEnableTeacherMusicSheetNum() + children.getEnableTeacherMusicSheetNum());
-                         musicTagVo.setMusicPlatformSheetNum(musicTagVo.getMusicPlatformSheetNum() + children.getMusicPlatformSheetNum());
-                         musicTagVo.setMusicTeacherSheetNum(musicTagVo.getMusicTeacherSheetNum() + children.getMusicTeacherSheetNum());
-                     });
-                     // 如果没有按名称/编号查询 或 父级标签包含了名称/编号 , 展示所有子集 标签列表子集收起
-                     if (StringUtil.isBlank(query.getIdAndName())
-                             || musicTagVo.getName().contains(query.getIdAndName())
-                             || musicTagVo.getId().toString().contains(query.getIdAndName())) {
-                         musicTagVo.setChildren(childrenList);
-                     } else {
-                         // 如果名称查询中,父级不包含名称/编号,子集包含,只展示包含的子集,并且默认展开子集列表
-                         musicTagVo.setOpen(YesOrNoEnum.YES);
-                         List<MusicTagVo> childrenNameList = childrenList.stream()
-                                                                .filter(vo -> vo.getName().contains(query.getIdAndName())
-                                                                        ||vo.getId().toString().contains(query.getIdAndName()))
-                                                                .collect(Collectors.toList());
-                         musicTagVo.setChildren(childrenNameList);
-                     }
-                 });
+                        .forEach(musicTagVo -> {
+                            List<MusicTagVo> childrenList = musicTagMap.get(musicTagVo.getId().toString());
+                            if (CollectionUtils.isEmpty(childrenList)) {
+                                return;
+                            }
+                            childrenList.forEach(children -> {
+                                musicTagVo.setEnablePlatformMusicSheetNum(musicTagVo.getEnablePlatformMusicSheetNum() + children.getEnablePlatformMusicSheetNum());
+                                musicTagVo.setEnableTeacherMusicSheetNum(musicTagVo.getEnableTeacherMusicSheetNum() + children.getEnableTeacherMusicSheetNum());
+                                musicTagVo.setMusicPlatformSheetNum(musicTagVo.getMusicPlatformSheetNum() + children.getMusicPlatformSheetNum());
+                                musicTagVo.setMusicTeacherSheetNum(musicTagVo.getMusicTeacherSheetNum() + children.getMusicTeacherSheetNum());
+                                musicTagVo.setMusicPlatformAlbumNum(musicTagVo.getMusicPlatformAlbumNum() + children.getMusicPlatformAlbumNum());
+                                musicTagVo.setEnablePlatformAlbumNum(musicTagVo.getEnablePlatformAlbumNum() + children.getEnablePlatformAlbumNum());
+                            });
+                        });
          return musicTagVoIPage;
      }
 
@@ -113,19 +98,10 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
      */
     private boolean checkTagBeUsed(Long musicTagId) {
 
-        List<MusicTag> list = this.lambdaQuery()
-                                  .eq(MusicTag::getParentTagId, musicTagId)
-                                  .eq(MusicTag::getDelFlag, false)
-                                  .list();
-        List<Long> longs = list.stream().map(MusicTag::getId).collect(Collectors.toList());
-        if (CollectionUtils.isEmpty(longs)) {
-            longs = new ArrayList<>();
-        }
+        List<Long> longs = new ArrayList<>();
         longs.add(musicTagId);
-        if (baseMapper.checkTagBeUsedMusicAblum(longs) >0) return true;
-        if (baseMapper.checkTagBeUsedMusicSheet(longs) >0) return true;
-
-        return false;
+        if (baseMapper.checkTagBeUsedMusicAlbum(longs) >0) return true;
+        return baseMapper.checkTagBeUsedMusicSheet(longs) > 0;
 
     }
 
@@ -138,29 +114,16 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
         }
         MusicTag musicTag = new MusicTag();
         musicTag.setId(musicTagId);
-        if (tag.getState().getCode().equals(YesOrNoEnum.NO.getCode())) {
-            musicTag.setState(YesOrNoEnum.YES);
-            return this.updateById(musicTag);
-        } else {
-            // 一级停用,二级也停用
-            if (musicTag.getParentTagId() == null || musicTag.getParentTagId() ==0) {
-                return this.lambdaUpdate()
-                    .eq(MusicTag::getParentTagId,musicTagId)
-                    .or(wrapper -> wrapper.eq(MusicTag::getId,musicTagId))
-                    .set(MusicTag::getState,YesOrNoEnum.NO)
-                    .update();
-            } else {
-                musicTag.setState(YesOrNoEnum.NO);
-                return this.updateById(musicTag);
-            }
-        }
+        musicTag.setState(tag.getState().equals(YesOrNoEnum.YES)?YesOrNoEnum.NO:YesOrNoEnum.YES);
+        return this.updateById(musicTag);
+
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public boolean createMusicTag(MusicTagSaveDto musicTagSaveDto) {
 
-        if (checkNameRepeat(musicTagSaveDto.getName(), musicTagSaveDto.getId())) {
+        if (checkNameRepeat(musicTagSaveDto.getName(), musicTagSaveDto.getId(),musicTagSaveDto.getType())) {
             throw new BizException("标签名称重复");
         }
 
@@ -168,11 +131,13 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
         MusicTag musicTag = new MusicTag();
         musicTag.setDelFlag(false);
         musicTag.setState(YesOrNoEnum.NO);
+        musicTag.setType(musicTagSaveDto.getType());
         if (musicTagSaveDto.getParentTagId() == null) {
             musicTag.setParentTagId(0L);
         } else {
             musicTag.setParentTagId(musicTagSaveDto.getParentTagId());
         }
+        musicTag.setSortNumber(musicTagSaveDto.getSortNumber());
         musicTag.setName(musicTagSaveDto.getName());
         musicTag.setCreateTime(new Date());
         musicTag.setUpdateTime(new Date());
@@ -186,12 +151,14 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
      *
      * @param name 名称
      * @param id 标签id, 更新
+     * @param type
      * @return boolean
      */
-    private boolean checkNameRepeat(String name,Long id) {
+    private boolean checkNameRepeat(String name, Long id, String type) {
         LambdaQueryChainWrapper<MusicTag> eq = this.lambdaQuery()
-                                                   .eq(MusicTag::getDelFlag, YesOrNoEnum.NO.getCode())
-                                                   .eq(MusicTag::getName, name);
+                .eq(MusicTag::getDelFlag, YesOrNoEnum.NO.getCode())
+                .eq(MusicTag::getName, name)
+                .eq(MusicTag::getType,type);
         if (id != null) {
             eq.ne(MusicTag::getId,id);
         }
@@ -202,7 +169,7 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
     @Transactional(rollbackFor = Exception.class)
     public boolean updateMusicTag(MusicTagSaveDto musicTagSaveDto) {
 
-        if (checkNameRepeat(musicTagSaveDto.getName(), musicTagSaveDto.getId())) {
+        if (checkNameRepeat(musicTagSaveDto.getName(), musicTagSaveDto.getId(), musicTagSaveDto.getType())) {
             throw new BizException("标签名称重复");
         }
         MusicTag oldTag = super.getById(musicTagSaveDto.getId());
@@ -214,6 +181,8 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
         MusicTag musicTag = new MusicTag();
         musicTag.setDelFlag(false);
         musicTag.setId(musicTagSaveDto.getId());
+        musicTag.setSortNumber(musicTagSaveDto.getSortNumber());
+        musicTag.setType(musicTagSaveDto.getType());
         if (musicTagSaveDto.getParentTagId() == null) {
             musicTag.setParentTagId(0L);
         } else {
@@ -226,36 +195,25 @@ public class MusicTagServiceImpl extends ServiceImpl<MusicTagDao, MusicTag> impl
     }
 
     @Override
-    public List<MusicTagVo> selectMusicTagTree() {
+    public List<MusicTagVo> selectMusicTagTree(String type) {
+        if (StringUtil.isEmpty(type)) {
+            type = "MUSIC";
+        }
         List<MusicTag> list = this.lambdaQuery()
                 .eq(MusicTag::getDelFlag,YesOrNoEnum.NO.getCode())
                 .eq(MusicTag::getState,YesOrNoEnum.YES.getCode())
+                .eq(MusicTag::getType,type)
+                .orderByDesc(MusicTag::getSortNumber)
                 .list();
         if (list == null) {
             return new ArrayList<>();
         }
-        List<MusicTagVo> musicTagVoList = list.stream().map(musicTag -> {
+
+        return list.stream().map(musicTag -> {
             MusicTagVo musicTagVo = new MusicTagVo();
             BeanUtils.copyProperties(musicTag, musicTagVo);
             return musicTagVo;
         }).collect(Collectors.toList());
-
-        List<MusicTagVo> tree = new ArrayList<>();
-        for (MusicTagVo musicTagVo : musicTagVoList) {
-            if (musicTagVo.getParentTagId() == null || musicTagVo.getParentTagId() == 0) {
-                tree.add(musicTagVo);
-            }
-            for (MusicTagVo tagVo : musicTagVoList) {
-                if (tagVo.getParentTagId() != null && tagVo.getParentTagId() != 0
-                        && tagVo.getParentTagId().equals(musicTagVo.getId())) {
-                    if (musicTagVo.getChildren() == null) {
-                        musicTagVo.setChildren(new ArrayList<>());
-                    }
-                    musicTagVo.getChildren().add(tagVo);
-                }
-            }
-        }
-        return tree;
     }
 
     @Override

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

@@ -11,19 +11,26 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.service.MusicCompareRecordStatService;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
+import com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
+import com.yonge.toolset.base.util.ThreadPool;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.joda.time.DateTime;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.util.CollectionUtils;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
@@ -55,24 +62,14 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	private final static Logger log = LoggerFactory.getLogger(SysMusicCompareRecordServiceImpl.class);
 	@Autowired
 	private SysMusicCompareRecordDao sysMusicCompareRecordDao;
-	@Autowired
-	private TeacherDao teacherDao;
-	@Autowired
-	private StudentDao studentDao;
-	@Autowired
-	private SysMessageService sysMessageService;
-	
-    @Autowired
-    private SysUserFeignService sysUserFeignService;
 
 	@Autowired
 	private SysConfigService sysConfigService;
 
 	@Autowired
-	private ActivityEvaluationRecordService activityEvaluationRecordService;
-
-	@Autowired
 	private MusicSheetDao musicSheetDao;
+	@Autowired
+	private MusicCompareRecordStatService musicCompareRecordStatService;
 
 	@Override
 	public BaseDAO<Long, SysMusicCompareRecord> getDAO() {
@@ -82,17 +79,138 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 	@Override
 	public long insert(SysMusicCompareRecord bean) {
 		// 保存评测记录
-		long insert = super.insert(bean);
+		long record = super.insert(bean);
+
+		if (record > 0) {
+			// 生成曲目评测统计数据
+			saveMusicCompareRecordStatInfo(bean);
+		}
+
+		return record;
+	}
+
+	/**
+	 * 生成曲目统计数据
+	 * @param record SysMusicCompareRecord
+	 */
+	private void saveMusicCompareRecordStatInfo(SysMusicCompareRecord record) {
+
+		ThreadPool.getExecutor().submit(() -> {
+			try {
+
+				// 统计单曲练习时长,频率;评测时长、频率
+				ClientEnum clientType = Optional.of(ClientEnum.valueOf(record.getClientId().toUpperCase()))
+						.orElse(ClientEnum.STUDENT);
+
+				// 单曲统计
+				MusicCompareWrapper.RecordInfo musicStatRecord = MusicCompareWrapper.RecordInfo.builder()
+						.musicSheetId(record.getMusicSheetId())
+						.clientId(clientType)
+						.userId(0L)
+						.recentTime(DateTime.now().getMillis())
+						.build();
+
+				// 用户单曲统计
+				MusicCompareWrapper.RecordInfo userStatRecord = MusicCompareWrapper.RecordInfo.builder()
+						.musicSheetId(record.getMusicSheetId())
+						.clientId(clientType)
+						.userId(record.getUserId())
+						.recentTime(DateTime.now().getMillis())
+						.build();
+
+				// 按练习、评测分别进行统计
+				Lists.newArrayList(FeatureType.values()).parallelStream().forEach(dataType -> {
+
+					MusicCompareWrapper.RecordQueryInfo queryInfo = MusicCompareWrapper.RecordQueryInfo.builder()
+							.clientId(record.getClientId())
+							.musicSheetId(record.getMusicSheetId())
+							.feature(dataType)
+							.build();
+
+					if (FeatureType.CLOUD_STUDY_EVALUATION == dataType) {
+						// 只统计生成评测报告数据
+						queryInfo.setScoreData(true);
+					}
+
+					// 曲目统计
+					List<StatGroupWrapper> musicWrappers = sysMusicCompareRecordDao.selectMusicCompareRecordStatInfo(queryInfo);
 
-		return insert;
+					// 用户曲目统计
+					queryInfo.setUserId(record.getUserId());
+
+					List<StatGroupWrapper> userMusicWrappers = sysMusicCompareRecordDao.selectMusicCompareRecordStatInfo(queryInfo);
+
+					switch (dataType) {
+						case CLOUD_STUDY_TRAIN: // 练习
+							{
+								// 先统计练习曲目
+								if (CollectionUtils.isNotEmpty(musicWrappers)) {
+
+									StatGroupWrapper wrapper = musicWrappers.get(0);
+
+									musicStatRecord.trainDuration(wrapper.getNumber().longValue())
+											.trainFrequency(wrapper.getTotal().longValue());
+								}
+
+								// 在按用户统计
+								if (CollectionUtils.isNotEmpty(userMusicWrappers)) {
+									StatGroupWrapper wrapper = userMusicWrappers.get(0);
+
+									userStatRecord.trainDuration(wrapper.getNumber().longValue())
+											.trainFrequency(wrapper.getTotal().longValue());
+								}
+							}
+							break;
+						case CLOUD_STUDY_EVALUATION: // 评测
+							{
+								// 先统计评测曲目
+								if (CollectionUtils.isNotEmpty(musicWrappers)) {
+
+									StatGroupWrapper wrapper = musicWrappers.get(0);
+
+									musicStatRecord.evaluateDuration(wrapper.getNumber().longValue())
+											.evaluateFrequency(wrapper.getTotal().longValue());
+								}
+
+								// 在按用户统计
+								if (CollectionUtils.isNotEmpty(userMusicWrappers)) {
+									StatGroupWrapper wrapper = userMusicWrappers.get(0);
+
+									userStatRecord.evaluateDuration(wrapper.getNumber().longValue())
+											.evaluateFrequency(wrapper.getTotal().longValue());
+								}
+							}
+							break;
+						default:
+							break;
+					}
+				});
+
+				List<MusicCompareWrapper.RecordInfo> recordInfos = Lists.newArrayList(musicStatRecord, userStatRecord);
+
+				musicCompareRecordStatService.batchUpdateMusicCompareRecordStat(recordInfos);
+
+			} catch (Exception e) {
+				log.error("MusicCompareRecordStat userId={}, musicId={}", record.getUserId(), record.getMusicSheetId(), e);
+			}
+		});
 	}
 
 	@Override
 	@Transactional
 	public void saveMusicCompareData(SysMusicCompareRecord sysMusicCompareRecord) {
-		
-		sysMusicCompareRecordDao.update(sysMusicCompareRecord);
 
+		int record = sysMusicCompareRecordDao.update(sysMusicCompareRecord);
+
+		if (record > 0) {
+			SysMusicCompareRecord info = sysMusicCompareRecordDao.get(sysMusicCompareRecord.getId());
+
+			if (Objects.nonNull(info)) {
+
+				// 生成曲目评测统计数据
+				saveMusicCompareRecordStatInfo(info);
+			}
+		}
 	}
 
 	@Override
@@ -147,8 +265,9 @@ public class SysMusicCompareRecordServiceImpl extends BaseServiceImpl<Long, SysM
 
 		List<StudentTrainChartDto> userTrainChartData = new ArrayList<>();
 		if(queryInfo.getPage()==1){
-			userTrainOverView = sysMusicCompareRecordDao.getUserTrainOverView(queryInfo.getUserId());
-			userTrainChartData = sysMusicCompareRecordDao.getUserTrainChartData(queryInfo.getUserId(), queryInfo.getStartTime(), queryInfo.getEndTime());
+			userTrainOverView = sysMusicCompareRecordDao.getUserTrainOverView(queryInfo.getUserId(),queryInfo.getClientId());
+			userTrainChartData = sysMusicCompareRecordDao.getUserTrainChartData(queryInfo.getUserId(), queryInfo.getStartTime(),
+																				queryInfo.getEndTime(),queryInfo.getClientId());
 		}
 
 		if(CollectionUtils.isEmpty(userTrainChartData)||userTrainChartData.size()!=7){

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

@@ -23,6 +23,10 @@ public class MusicSheetDetailVo extends MusicSheet {
     @ApiModelProperty("是否能播放(0:否,1:是) 学生端进入小酷Ai判断 试用/完整 播放")
     private YesOrNoEnum play;
 
+
+    @ApiModelProperty("收藏0:否,1:是")
+    private YesOrNoEnum favorite;
+
     @ApiModelProperty("订单状态(WAIT_PAY:待支付;PAYING:支付中,PAID:已付款)")
     private OrderStatusEnum orderStatus;
 
@@ -65,6 +69,15 @@ public class MusicSheetDetailVo extends MusicSheet {
     @ApiModelProperty("审核理由")
     private String auditReason;
 
+
+    public YesOrNoEnum getFavorite() {
+        return favorite;
+    }
+
+    public void setFavorite(YesOrNoEnum favorite) {
+        this.favorite = favorite;
+    }
+
     public String getRealName() {
         return realName;
     }

+ 0 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetVo.java

@@ -29,9 +29,6 @@ public class MusicSheetVo extends MusicSheet {
     @ApiModelProperty("收藏 0:否,1:是")
     private YesOrNoEnum favorite;
 
-    @ApiModelProperty("收藏人数")
-    private Long favoriteCount;
-
     @ApiModelProperty("是否购买/VIP(0:否,1:是) ")
     private YesOrNoEnum play;
 
@@ -49,13 +46,6 @@ public class MusicSheetVo extends MusicSheet {
         this.albumSortNumber = albumSortNumber;
     }
 
-    public Long getFavoriteCount() {
-        return favoriteCount;
-    }
-
-    public void setFavoriteCount(Long favoriteCount) {
-        this.favoriteCount = favoriteCount;
-    }
 
     public String getAddName() {
         return addName;

+ 22 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicTagVo.java

@@ -40,6 +40,28 @@ public class MusicTagVo extends MusicTag{
 	@ApiModelProperty("老师乐谱数")
 	private Integer musicTeacherSheetNum= 0;
 
+	@ApiModelProperty("平台专辑启用数")
+	private Integer enablePlatformAlbumNum = 0;
+
+	@ApiModelProperty("平台专辑数")
+	private Integer musicPlatformAlbumNum= 0;
+
+	public Integer getEnablePlatformAlbumNum() {
+		return enablePlatformAlbumNum;
+	}
+
+	public void setEnablePlatformAlbumNum(Integer enablePlatformAlbumNum) {
+		this.enablePlatformAlbumNum = enablePlatformAlbumNum;
+	}
+
+	public Integer getMusicPlatformAlbumNum() {
+		return musicPlatformAlbumNum;
+	}
+
+	public void setMusicPlatformAlbumNum(Integer musicPlatformAlbumNum) {
+		this.musicPlatformAlbumNum = musicPlatformAlbumNum;
+	}
+
 	public Integer getEnablePlatformMusicSheetNum() {
 		return enablePlatformMusicSheetNum;
 	}

+ 4 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/StatGroupWrapper.java

@@ -22,4 +22,8 @@ public class StatGroupWrapper implements Serializable {
     private String gid; // 字符串分组ID
     private Double number;
 
+    // 拓展字段信息
+    private Long musicNum;
+    private Long durationNum;
+    private Long frequencyNum;
 }

+ 340 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/wrapper/music/MusicCompareWrapper.java

@@ -0,0 +1,340 @@
+package com.yonge.cooleshow.biz.dal.wrapper.music;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.FeatureType;
+import com.yonge.cooleshow.biz.dal.enums.HeardLevelEnum;
+import com.yonge.cooleshow.biz.dal.enums.MK;
+import com.yonge.cooleshow.biz.dal.enums.music.MusicCompareType;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Created by Eric.Shang on 2022/10/17.
+ */
+public class MusicCompareWrapper {
+
+    /**
+     * 统计汇总查询条件
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @EqualsAndHashCode(callSuper = false)
+    public static class StatQueryInfo extends QueryInfo {
+
+        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("用户ID ")
+        private Long userId;
+
+        @ApiModelProperty("排序类型 ")
+        private MusicCompareType compareType;
+
+        @ApiModelProperty("排序字段")
+        private String compareField;
+
+        @ApiModelProperty("排序方式 升序(ASC) 降序(DESC)")
+        private String sortType;
+
+        @ApiModelProperty("练习曲目")
+        private Boolean trainMusic;
+
+        @ApiModelProperty("评测曲目")
+        private Boolean evaluateMusic;
+
+        @ApiModelProperty("曲目ID")
+        private Long musicId;
+
+        @ApiModelProperty("曲目名称")
+        private String musicName;
+
+        @ApiModelProperty("开始时间")
+        private Long startTime;
+
+        @ApiModelProperty("结束时间")
+        private Long endTime;
+
+        public static StatQueryInfo from(String record) {
+
+            return JSON.parseObject(record, StatQueryInfo.class);
+        }
+
+        public String getCompareField() {
+            return getCompareType().getSortField();
+        }
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+
+        public StatQueryInfo trainMusic(Boolean trainMusic) {
+            this.trainMusic = trainMusic;
+            return this;
+        }
+
+        public StatQueryInfo evaluateMusic(Boolean evaluateMusic) {
+            this.evaluateMusic = evaluateMusic;
+            return this;
+        }
+    }
+
+    /**
+     * 曲目统计汇总信息
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordStat implements Serializable {
+
+        @ApiModelProperty("练习曲目总数")
+        private Long trainMusicNums;
+
+        @ApiModelProperty("使用时长")
+        private Long trainDuration;
+
+        @ApiModelProperty("使用次数")
+        private Long trainFrequency;
+
+        @ApiModelProperty("评测曲目总数")
+        private Long evaluateMusicNums;
+
+        @ApiModelProperty("评测时长")
+        private Long evaluateDuration;
+
+        @ApiModelProperty("评测次数")
+        private Long evaluateFrequency;
+
+        private List<RecordInfo> recordInfos;
+
+        public String jsonString() {
+
+            return JSON.toJSONString(this);
+        }
+
+
+        public RecordStat trainMusicNums(Long trainMusicNums) {
+            this.trainMusicNums = trainMusicNums;
+            return this;
+        }
+
+        public RecordStat trainDuration(Long trainDuration) {
+            this.trainDuration = trainDuration;
+            return this;
+        }
+
+        public RecordStat trainFrequency(Long trainFrequency) {
+            this.trainFrequency = trainFrequency;
+            return this;
+        }
+
+        public RecordStat evaluateMusicNums(Long evaluateMusicNums) {
+            this.evaluateMusicNums = evaluateMusicNums;
+            return this;
+        }
+
+        public RecordStat evaluateDuration(Long evaluateDuration) {
+            this.evaluateDuration = evaluateDuration;
+            return this;
+        }
+
+        public RecordStat evaluateFrequency(Long evaluateFrequency) {
+            this.evaluateFrequency = evaluateFrequency;
+            return this;
+        }
+    }
+
+    /**
+     * 曲目统计信息
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordInfo implements Serializable {
+
+        @ApiModelProperty("主键ID")
+        private Long id;
+
+        @ApiModelProperty("曲目ID")
+        private Long musicSheetId;
+
+        @ApiModelProperty("客户端标识")
+        private ClientEnum clientId;
+
+        @ApiModelProperty("用户编号")
+        private Long userId;
+
+        @ApiModelProperty("曲目名称")
+        private String musicName;
+
+        @ApiModelProperty("作曲人")
+        private String composer;
+
+        @ApiModelProperty("音乐标签编号")
+        private String musicTag;
+
+        @ApiModelProperty("音乐标签")
+        private String musicTagName;
+
+        @ApiModelProperty("使用时长")
+        private Long trainDuration;
+
+        @ApiModelProperty("使用次数")
+        private Long trainFrequency;
+
+        @ApiModelProperty("评测时长")
+        private Long evaluateDuration;
+
+        @ApiModelProperty("评测次数")
+        private Long evaluateFrequency;
+
+        @ApiModelProperty("最近使用时间")
+        private Long recentTime;
+
+        public String jsonString() {
+            return JSON.toJSONString(this);
+        }
+
+        public RecordInfo trainDuration(Long trainDuration) {
+            this.trainDuration = trainDuration;
+            return this;
+        }
+
+        public RecordInfo trainFrequency(Long trainFrequency) {
+            this.trainFrequency = trainFrequency;
+            return this;
+        }
+
+        public RecordInfo evaluateDuration(Long evaluateDuration) {
+            this.evaluateDuration = evaluateDuration;
+            return this;
+        }
+
+        public RecordInfo evaluateFrequency(Long evaluateFrequency) {
+            this.evaluateFrequency = evaluateFrequency;
+            return this;
+        }
+
+        public RecordInfo recentTime(Long recentTime) {
+            this.recentTime = recentTime;
+            return this;
+        }
+    }
+
+    /**
+     * 曲目练习记录查询
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordQueryInfo implements Serializable {
+
+        @ApiModelProperty("用户ID ")
+        private Long userId;
+
+        @ApiModelProperty("曲目编号 ")
+        private Long musicSheetId;
+
+        @ApiModelProperty("客户端类型 ")
+        private String clientId;
+
+        @ApiModelProperty("功能类型 ")
+        private FeatureType feature;
+
+        @ApiModelProperty("评测结果数据 ")
+        private Boolean scoreData;
+    }
+
+    /**
+     * 曲目评测查询条件
+     */
+    @Data
+    @Builder
+    @NoArgsConstructor
+    @AllArgsConstructor
+    @EqualsAndHashCode(callSuper = false)
+    public static class EvaluteQueryInfo extends QueryInfo {
+
+        @ApiModelProperty("客户端类型 TEACHER(老师端) STUDENT(学生端)")
+        private ClientEnum clientType;
+
+        @ApiModelProperty("用户ID ")
+        private Long userId;
+
+        @ApiModelProperty("曲目ID ")
+        private Long musicId;
+
+        @ApiModelProperty("评测难度")
+        private HeardLevelEnum heardLevel;
+
+        @ApiModelProperty("评测类型")
+        private FeatureType feature;
+
+        @ApiModelProperty("评测结果数据 ")
+        private Boolean scoreData;
+
+        @ApiModelProperty("开始时间")
+        private Date startTime;
+
+        @ApiModelProperty("结束时间")
+        private Date endTime;
+
+        public static EvaluteQueryInfo from(String record) {
+
+            return JSON.parseObject(record, EvaluteQueryInfo.class);
+        }
+
+        public FeatureType getFeature() {
+            return Optional.ofNullable(feature).orElse(FeatureType.CLOUD_STUDY_EVALUATION);
+        }
+    }
+
+    /**
+     * 曲目评测记录信息
+     */
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class RecordEvaluate implements Serializable {
+
+        @ApiModelProperty("评测记录ID ")
+        private Long id;
+
+        @ApiModelProperty("评测难度: 入门级,进阶级,大师级")
+        private HeardLevelEnum heardLevel;
+
+        @ApiModelProperty("总分 ")
+        private BigDecimal score;
+
+        @ApiModelProperty("音准 ")
+        private BigDecimal intonation;
+
+        @ApiModelProperty("节奏")
+        private BigDecimal cadence;
+
+        @ApiModelProperty("完成度 ")
+        private BigDecimal integrity;
+
+        @ApiModelProperty("评测时间")
+        @JsonFormat(pattern = MK.TIME_PATTERN, timezone = MK.TIME_ZONE)
+        private Date createTime;
+    }
+}

+ 130 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicCompareRecordStatMapper.xml

@@ -0,0 +1,130 @@
+<?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.MusicCompareRecordStatMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.MusicCompareRecordStat">
+        <id column="id_" property="id" />
+        <result column="music_sheet_id_" property="musicSheetId" />
+        <result column="client_id_" property="clientId" />
+        <result column="user_id_" property="userId" />
+        <result column="train_duration_" property="trainDuration" />
+        <result column="train_frequency_" property="trainFrequency" />
+        <result column="evaluate_duration_" property="evaluateDuration" />
+        <result column="evaluate_frequency_" property="evaluateFrequency" />
+        <result column="recent_time_" property="recentTime" />
+        <result column="create_time_" property="createTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id_, music_sheet_id_, client_id_, user_id_, train_duration_, train_frequency_, evaluate_duration_, evaluate_frequency_, recent_time_, create_time_
+    </sql>
+
+    <!--曲目统计查询-->
+    <resultMap id="MusicCompareRecordPageResultMap"
+               type="com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper$RecordInfo">
+        <id column="id_" property="id" />
+        <result column="music_sheet_id_" property="musicSheetId" />
+        <result column="train_duration_" property="trainDuration" />
+        <result column="train_frequency_" property="trainFrequency" />
+        <result column="evaluate_duration_" property="evaluateDuration" />
+        <result column="evaluate_frequency_" property="evaluateFrequency" />
+        <result column="recent_time_" property="recentTime" />
+        <result column="music_sheet_name_" property="musicName" />
+        <result column="composer_" property="composer" />
+        <result column="music_tag_" property="musicTag" />
+    </resultMap>
+    <select id="selectMusicCompareRecordPage" resultMap="MusicCompareRecordPageResultMap">
+        SELECT t1.id_, t1.music_sheet_id_, t1.user_id_, t1.train_duration_, t1.train_frequency_, t1.evaluate_duration_, t1.evaluate_frequency_, t1.recent_time_, t2.music_sheet_name_, t2.composer_, t2.music_tag_
+        FROM music_compare_record_stat t1 LEFT JOIN music_sheet t2 ON t1.music_sheet_id_ = t2.id_
+        <where>
+            <if test="record.clientType != null">
+                AND t1.client_id_ = #{record.clientType}
+            </if>
+            <if test="record.userId != null">
+                AND t1.user_id_ = #{record.userId}
+            </if>
+            <if test="record.startTime != null and record.endTime != null">
+                AND (t1.recent_time_ >= #{record.startTime} AND  t1.recent_time_ &lt;= #{record.endTime})
+            </if>
+            <if test="record.musicId != null">
+                AND t2.id_ = #{record.musicId}
+            </if>
+            <if test="record.musicName != null">
+                AND t2.music_sheet_name_ LIKE '%${record.musicName}%'
+            </if>
+        </where>
+        ORDER BY t1.${record.compareField} ${record.sortType}
+    </select>
+    <!--曲目统计查询-->
+
+    <!--用户曲目统计汇总-->
+    <select id="selectMusicCompareRecordStatInfo"
+            resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+        SELECT t1.user_id_ AS id, COUNT(DISTINCT t1.music_sheet_id_) AS musicNum,
+                <if test="record.trainMusic != null">
+                   SUM(t1.train_duration_) AS durationNum, SUM(t1.train_frequency_) AS frequencyNum
+                </if>
+                <if test="record.evaluateMusic != null">
+                   SUM(t1.evaluate_duration_) AS durationNum, SUM(t1.evaluate_frequency_) AS frequencyNum
+                </if>
+        FROM music_compare_record_stat t1
+        <where>
+            <if test="record.clientType != null">
+                AND t1.client_id_ = #{record.clientType}
+            </if>
+            <if test="record.userId != null">
+                AND t1.user_id_ = #{record.userId}
+            </if>
+            <if test="record.trainMusic != null">
+                AND t1.train_frequency_ > 0
+            </if>
+            <if test="record.evaluateMusic != null">
+                AND t1.evaluate_frequency_ > 0
+            </if>
+        </where>
+        GROUP BY t1.user_id_
+    </select>
+    <!--用户曲目统计汇总-->
+
+    <!--曲目评测记录查询-->
+    <resultMap id="MusicCompareEvaluatePageResultMap"
+               type="com.yonge.cooleshow.biz.dal.wrapper.music.MusicCompareWrapper$RecordEvaluate">
+        <id column="id_" property="id" />
+        <result column="score_" property="score" />
+        <result column="intonation_" property="intonation" />
+        <result column="cadence_" property="cadence" />
+        <result column="integrity_" property="integrity" />
+        <result column="heard_level_" property="heardLevel" />
+        <result column="create_time_" property="createTime" />
+    </resultMap>
+    <select id="selectMusicCompareEvaluatePage" resultMap="MusicCompareEvaluatePageResultMap">
+        SELECT t1.id_, t1.score_, t1.intonation_, t1.cadence_, t1.integrity_, t1.heard_level_, t1.create_time_
+        FROM sys_music_compare_record t1
+        <where>
+            <if test="record.clientType != null">
+                AND t1.client_id_ = #{record.clientType}
+            </if>
+            <if test="record.userId != null">
+                AND t1.user_id_ = #{record.userId}
+            </if>
+            <if test="record.musicId != null">
+                AND t1.music_sheet_id_ = #{record.musicId}
+            </if>
+            <if test="record.heardLevel != null">
+                AND t1.heard_level_ = #{record.heardLevel}
+            </if>
+            <if test="record.scoreData != null">
+                AND t1.score_data_ != ''
+            </if>
+            <if test="record.feature != null">
+                AND t1.feature_ = #{record.feature}
+            </if>
+            <if test="record.startTime != null and record.endTime != null">
+                AND (t1.create_time_ >= #{record.startTime} AND t1.create_time_ &lt;= #{record.endTime})
+            </if>
+        </where>
+    </select>
+    <!--曲目评测记录查询-->
+</mapper>

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

@@ -15,9 +15,4 @@
 		id_, user_id_, music_sheet_id_, favorite_time_, favorite_flag_
 	</sql>
 
-	<select id="selectMusicSheetFavoriteNum" resultType="long">
-		select count(1)
-		from music_favorite
-		where music_sheet_id_ = #{musicSheetId}
-    </select>
 </mapper>

+ 41 - 19
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml

@@ -11,6 +11,8 @@
         <result column="audio_type_" jdbcType="VARCHAR" property="audioType"/>
         <result column="music_tag_" jdbcType="VARCHAR" property="musicTag"/>
         <result column="play_speed_" jdbcType="INTEGER" property="playSpeed"/>
+        <result column="favorite_count_" jdbcType="INTEGER" property="favoriteCount"/>
+        <result column="first_pass_audit_time_" jdbcType="TIMESTAMP" property="firstPassAuditTime"/>
         <result column="can_evaluate_" jdbcType="TINYINT" property="canEvaluate"/>
         <result column="show_fingering_" jdbcType="TINYINT" property="showFingering"/>
         <result column="charge_type_" jdbcType="TINYINT" property="chargeType"/>
@@ -43,6 +45,8 @@
         t.audio_type_ as audioType,
         t.music_tag_ as musicTag,
         t.play_speed_ as playSpeed,
+        t.favorite_count_ as favoriteCount,
+        t.first_pass_audit_time_ as firstPassAuditTime,
         t.can_evaluate_ as canEvaluate,
         t.show_fingering_ as showFingering,
         t.charge_type_ as chargeType,
@@ -159,8 +163,6 @@
             where find_in_set(mt.id_,t.music_tag_) and mt.del_flag_ = 0  and mt.state_ = 1) as musicTagNames
         ,(select group_concat(s.name_) from subject s
             where find_in_set(s.id_,t.music_subject_) and s.del_flag_ = 0 ) as subjectNames
-        ,(select count(1) from music_favorite f
-            where f.music_sheet_id_ = t.id_) as favoriteCount
         ,amr.sort_number_ as albumSortNumber
         from music_sheet t
         left join album_music_relate amr on t.id_ = amr.music_sheet_id_
@@ -291,7 +293,9 @@
         <result column="reason" jdbcType="VARCHAR" property="reason"/>
         <result column="accompanimentType" jdbcType="VARCHAR" property="accompanimentType"/>
         <result column="notation" jdbcType="VARCHAR" property="notation"/>
-	<result column="musicImg" jdbcType="VARCHAR" property="musicImg"/>
+	    <result column="musicImg" jdbcType="VARCHAR" property="musicImg"/>
+	    <result column="favoriteCount" jdbcType="VARCHAR" property="favoriteCount"/>
+	    <result column="firstPassAuditTime" jdbcType="VARCHAR" property="firstPassAuditTime"/>
         <result column="realName" jdbcType="VARCHAR" property="realName"/>
         <result column="auditTime" jdbcType="VARCHAR" property="auditTime"/>
         <result column="auditName" jdbcType="VARCHAR" property="auditName"/>
@@ -315,26 +319,14 @@
         ,su.avatar_ as addUserAvatar
         ,(select group_concat(mt.name_) from music_tag mt
         where find_in_set(mt.id_,t.music_tag_) and mt.del_flag_ = 0  and mt.state_ = 1) as musicTagNames
-        ,(select count(1) as num from music_favorite af
-                left join sys_user su on af.user_id_ = su.id_
-                where su.del_flag_ = 0 and af.music_sheet_id_ = t.id_) as favoriteCount
         ,(select group_concat(s.name_) from subject s
         where find_in_set(s.id_,t.music_subject_)  and s.del_flag_ = 0) as subjectNames
         <if test="param.studentId != null">
             ,if(mf.id_ is not null,1,0) as favorite
-<!--            ,case when mspr.id_ is not null then 1-->
-<!--                when t.charge_type_ = 'FREE' then 1-->
-<!--                else 0 end as play-->
         </if>
         from music_sheet t
         left join sys_user su on t.create_by_ = su.id_
-        left join (select count(1) as num,mf.music_sheet_id_
-            from music_favorite mf group by mf.music_sheet_id_) t2 on t2.music_sheet_id_ = t.id_
         <if test="param.studentId != null">
-<!--            left join music_sheet_purchase_record mspr-->
-<!--                on mspr.music_sheet_id_ = t.id_-->
-<!--                and mspr.student_id_ = #{param.studentId}-->
-<!--                and order_status_ = 'PAID'-->
             left join music_favorite mf on (t.id_ = mf.music_sheet_id_ and mf.user_id_ = #{param.studentId} <if test="clientType != null"> AND mf.client_type_ = #{clientType}</if> )
         </if>
         <where>
@@ -345,9 +337,23 @@
             </if>
         </where>
         order by
-        <if test="param.myself == null or param.myself == false ">
-            t.top_flag_ desc, t.sort_number_ desc, t2.num desc,
-        </if>
+        <choose>
+            <when test="param.musicSortType != null and param.musicSortType.code == 'TOP'">
+                t.top_flag_ desc, t.sort_number_ desc,
+            </when>
+            <when test="param.musicSortType != null and param.musicSortType.code == 'HOT'">
+                t.favorite_count_ desc,
+            </when>
+            <when test="param.musicSortType != null and param.musicSortType.code == 'NEW'">
+                t.first_pass_audit_time_ desc,
+            </when>
+            <otherwise>
+                <if test="param.myself == null or param.myself == false ">
+                    t.top_flag_ desc, t.sort_number_ desc, t.favorite_count_ desc,
+                </if>
+            </otherwise>
+        </choose>
+
         t.id_ desc
     </select>
 
@@ -410,7 +416,7 @@
         where find_in_set(mt.id_,t.music_tag_) and mt.del_flag_ = 0  and mt.state_ = 1) as musicTagNames
         ,(select group_concat(s.name_) from subject s where find_in_set(s.id_,t.music_subject_) ) as subjectNames
         ,if(mf.id_ is not null,1,0) as favorite
-        from music_sheet_practice_record mspr
+        from sys_music_compare_record mspr
         left join music_sheet t on mspr.music_sheet_id_ = t.id_
         left join sys_user su on t.create_by_ = su.id_
         left join music_favorite mf on (t.id_ = mf.music_sheet_id_ and mspr.user_id_ = mf.user_id_ <if test="param.clientType != null"> AND mf.client_type_ = #{param.clientType}</if> )
@@ -737,5 +743,21 @@
         </where>
         GROUP BY t1.music_sheet_id_
     </select>
+
+    <update id="updateFavoriteCount">
+        update music_sheet set favorite_count_ =
+        <choose>
+            <when test="state.code == 0">
+                favorite_count_ - 1
+            </when>
+            <when test="state.code == 1">
+                favorite_count_ + 1
+            </when>
+            <otherwise>
+                favorite_count_
+            </otherwise>
+        </choose>
+        where id_ = #{musicSheetId}
+    </update>
     <!--单曲专辑数量统计-->
 </mapper>

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

@@ -19,7 +19,7 @@
 	<select id="selectPracticeMusicIdPage" resultType="java.lang.Long">
         select t.id_ from  (select
         max(mspr.id_) as id_
-        from music_sheet_practice_record mspr
+        from sys_music_compare_record mspr
         left join music_sheet ms on mspr.music_sheet_id_ = ms.id_
         <where>
             <if test="param.auditStatus !=null">

+ 15 - 29
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicTagMapper.xml

@@ -6,6 +6,8 @@
         <result column="parent_tag_id_" property="parentTagId" />
         <result column="name_" property="name" />
         <result column="state_" property="state" />
+        <result column="sort_number_" property="sortNumber" />
+        <result column="type_" property="type" />
         <result column="del_flag_" property="delFlag" />
         <result column="create_time_" property="createTime" />
         <result column="update_time_" property="updateTime" />
@@ -19,6 +21,8 @@
         , t.parent_tag_id_ as parentTagId
         , t.name_ as name
         , t.state_ as state
+        , t.type_ as type
+        , t.sort_number_ as sortNumber
         , t.del_flag_ as delFlag
         , t.create_time_ as createTime
         , t.update_time_ as updateTime
@@ -40,42 +44,22 @@
 		FROM music_tag t
         left join sys_user su on t.update_by_ = su.id_
         <where>
-            t.parent_tag_id_ = 0 and t.del_flag_ = 0
+            t.del_flag_ = 0
             <if test="param.state != null">
                 and t.state_ = #{param.state}
             </if>
+            <if test="param.type != null and param.type != ''">
+                and t.type_ = #{param.type}
+            </if>
             <if test="param.idAndName != null and param.idAndName != ''">
                 and ( t.id_ like concat( '%',#{param.idAndName},'%') or
-                    t.name_ like  concat ('%',#{param.idAndName},'%') or
-                    exists(select mt.parent_tag_id_ from music_tag mt
-                        where (mt.name_ like concat( '%',#{param.idAndName},'%') or mt.id_ like concat('%',#{param.idAndName},'%') )
-                        and mt.parent_tag_id_ = t.id_ and mt.del_flag_ = 0
-                    )
+                    t.name_ like  concat ('%',#{param.idAndName},'%')
                     )
             </if>
         </where>
+        order by  t.sort_number_ desc,t.id_ desc
 	</select>
 
-	<select id="getChildren" resultType="com.yonge.cooleshow.biz.dal.vo.MusicTagVo">
-        SELECT
-        <include refid="baseColumns" />,
-        su.username_ as updateName
-        FROM music_tag t
-        left join sys_user su on t.update_by_ = su.id_
-        <where>
-            t.del_flag_ = 0
-            <if test="id != null">
-                and t.parent_tag_id_ = #{id}
-            </if>
-            <if test="state != null">
-                and t.state_ = #{state}
-            </if>
-            <if test="idAndName != null and idAndName != ''">
-                and ( t.id_ like concat( '%',#{idAndName},'%') or
-                t.name_ like  concat ('%',#{idAndName},'%')
-            </if>
-        </where>
-    </select>
 
 	<select id="getChildrenByParentIdList" resultType="com.yonge.cooleshow.biz.dal.vo.MusicTagVo">
         SELECT
@@ -84,13 +68,15 @@
         (select count(1) from music_sheet ms where find_in_set(t.id_,ms.music_tag_) and ms.del_flag_ = 0 and  ms.state_ = 1 and ms.source_type_ = 'PLATFORM') as enablePlatformMusicSheetNum,
         (select count(1) from music_sheet ms where find_in_set(t.id_,ms.music_tag_) and ms.del_flag_ = 0  and ms.source_type_ = 'PLATFORM') as musicPlatformSheetNum,
         (select count(1) from music_sheet ms where find_in_set(t.id_,ms.music_tag_) and ms.del_flag_ = 0 and ms.source_type_ = 'TEACHER' and ms.audit_status_ = 'PASS') as musicTeacherSheetNum,
-        (select count(1) from music_sheet ms where find_in_set(t.id_,ms.music_tag_) and ms.del_flag_ = 0  and ms.source_type_ = 'TEACHER' and ms.state_ = 1 and ms.audit_status_ = 'PASS') as enableTeacherMusicSheetNum
+        (select count(1) from music_sheet ms where find_in_set(t.id_,ms.music_tag_) and ms.del_flag_ = 0  and ms.source_type_ = 'TEACHER' and ms.state_ = 1 and ms.audit_status_ = 'PASS') as enableTeacherMusicSheetNum,
+        (select count(1) from music_album ma where find_in_set(t.id_,ma.album_tag_) and ma.del_flag_ = 0    and ma.album_status_ = 1) as enablePlatformAlbumNum,
+        (select count(1) from music_album ma where find_in_set(t.id_,ma.album_tag_) and ma.del_flag_ = 0 ) as musicPlatformAlbumNum
         FROM music_tag t
         left join sys_user su on t.update_by_ = su.id_
         <where>
             t.del_flag_ = 0
             <if test="longList != null and longList.size() != 0">
-                and t.parent_tag_id_ in
+                and t.id_ in
                 <foreach collection="longList" close=")" item="item" open="(" separator=",">
                     #{item}
                 </foreach>
@@ -115,7 +101,7 @@
         </where>
     </select>
 
-    <select id="checkTagBeUsedMusicAblum" resultType="java.lang.Integer">
+    <select id="checkTagBeUsedMusicAlbum" resultType="java.lang.Integer">
 
         select count(1) from music_album ms
         <where>

+ 37 - 2
cooleshow-user/user-biz/src/main/resources/config/mybatis/SysMusicCompareRecordMapper.xml

@@ -129,6 +129,9 @@
 	<sql id="queryCondition">
 		<where>
 			smcr.score_data_ is not null and smcr.score_data_ != ''
+			<if test="clientId != null and clientId != ''">
+				and smcr.client_id_ = #{clientId}
+			</if>
 			<if test="userId!=null">
 				AND smcr.user_id_=#{userId}
 			</if>
@@ -174,7 +177,7 @@
 			COUNT(DISTINCT DATE(smcr.create_time_)) trainDays,
 			SUM(smcr.play_time_) trainTime
 		FROM sys_music_compare_record smcr
-		WHERE smcr.user_id_=#{userId} and smcr.client_id_ = 'student'
+		WHERE smcr.user_id_=#{userId} and smcr.client_id_ = #{clientId}
 	</select>
 
 	<select id="getUserTrainChartData" resultType="com.yonge.cooleshow.biz.dal.dto.StudentTrainChartDto">
@@ -183,7 +186,7 @@
 			COUNT(DISTINCT smcr.behavior_id_) trainNum,
 			SUM(smcr.play_time_) trainTime
 		FROM sys_music_compare_record smcr
-		WHERE smcr.user_id_=#{userId}  and smcr.client_id_ = 'student'
+		WHERE smcr.user_id_=#{userId}  and smcr.client_id_ = #{clientId}
 		  AND DATE_FORMAT(smcr.create_time_, '%Y-%m-%d') BETWEEN #{startTime} AND #{endTime}
 		GROUP BY DATE_FORMAT(smcr.create_time_, '%Y-%m-%d')
 		ORDER BY trainDate;
@@ -301,4 +304,36 @@
 		WHERE user_id_=#{userId} AND monday_ = #{monday} AND heard_level_ = #{heardLevel, typeHandler=com.yonge.toolset.mybatis.dal.CustomEnumTypeHandler}
 		ORDER BY score_ DESC LIMIT 1
 	</select>
+
+	<!--曲目练习统计-->
+	<select id="selectMusicCompareRecordStatInfo"
+			resultType="com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper">
+		SELECT
+		    t1.music_sheet_id_ AS id, SUM(t1.play_time_) AS number
+			<choose>
+				<when test="record.feature.code == 'CLOUD_STUDY_TRAIN'">, COUNT(DISTINCT t1.behavior_id_) AS total</when>
+				<otherwise>, COUNT(t1.id_) AS total</otherwise>
+			</choose>
+		FROM sys_music_compare_record t1
+		<where>
+			<if test="record.musicSheetId != null">
+				AND t1.music_sheet_id_ = #{record.musicSheetId}
+			</if>
+			<if test="record.userId != null">
+				AND t1.user_id_ = #{record.userId}
+			</if>
+			<if test="record.clientId != null">
+				AND t1.client_id_ = #{record.clientId}
+			</if>
+			<if test="record.feature != null">
+				AND t1.feature_ = #{record.feature}
+			</if>
+			<if test="record.scoreData != null">
+				AND t1.score_data_ != ''
+			</if>
+		</where>
+		GROUP BY t1.music_sheet_id_ <if test="record.userId != null">, t1.user_id_</if>
+	</select>
+	<!--曲目练习统计-->
+
 </mapper>

+ 1 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/config/ResourceServerConfig.java

@@ -28,7 +28,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                 .authorizeRequests()
                 .antMatchers("/task/**")
                 .hasIpAddress("0.0.0.0/0")
-                .antMatchers("/wechat/*", "/v2/api-docs", "/code/*","/open/**")
+                .antMatchers("/wechat/*", "/v2/api-docs", "/code/*","/open/**","/sysMusicRecord/getLastEvaluationMusicalNotesPlayStats","/sysConfig/queryByParamNameList","/music/sheet/detail/**")
                 .permitAll().anyRequest().authenticated().and().httpBasic();
     }
 

+ 73 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/MusicSheetController.java

@@ -1,5 +1,7 @@
 package com.yonge.cooleshow.student.controller;
 
+import com.yonge.cooleshow.biz.dal.dto.AppMusicSheetVo;
+import com.yonge.cooleshow.biz.dal.enums.MusicSortType;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
@@ -45,6 +47,8 @@ import com.yonge.toolset.base.util.StringUtil;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.toolset.utils.idcard.IdcardInfoExtractor;
 
+import java.util.ArrayList;
+
 /**
  * 曲谱表 web 控制层
  * @author yzp
@@ -79,7 +83,7 @@ public class MusicSheetController extends BaseController {
     public HttpResponseResult<MusicSheetDetailVo> detail(@ApiParam(value = "曲谱编号", required = true) @PathVariable("id") Long id) {
         SysUser sysUser = sysUserFeignService.queryUserInfo();
         if (sysUser == null  || sysUser.getId() == null) {
-            return failed("用户信息获取失败");
+            sysUser = null;
         }
         return succeed(musicSheetService.detail(id, sysUser, ClientEnum.STUDENT));
     }
@@ -245,6 +249,26 @@ public class MusicSheetController extends BaseController {
     }
 
 
+
+    /**
+     * 最近练习
+     */
+    @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));
+    }
+
     /**
      * 检查实名认证
      */
@@ -288,4 +312,52 @@ public class MusicSheetController extends BaseController {
         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);
+    }
 }

+ 2 - 2
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/MusicTagController.java

@@ -26,8 +26,8 @@ public class MusicTagController extends BaseController {
 	 */
 	@GetMapping("/tree")
 	@ApiOperation(value = "查询标签树列表")
-	public HttpResponseResult<List<MusicTagVo>> tree() {
-		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree();
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
 		return succeed(treeList);
 	}
 

+ 23 - 1
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/StudentController.java

@@ -8,6 +8,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.QueryMyFollowSearch;
 import com.yonge.cooleshow.biz.dal.entity.Subject;
 import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
 import com.yonge.cooleshow.biz.dal.service.SysUserService;
+import com.yonge.cooleshow.biz.dal.vo.StudentVo;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.mybatis.support.PageUtil;
 import com.yonge.cooleshow.biz.dal.vo.MyFollow;
@@ -43,9 +44,30 @@ public class StudentController extends BaseController {
     private SysUserService sysUserService;
 
 
+    @ApiOperation(value = "查询指定学员信息")
+    @GetMapping("/queryUserById")
+    public HttpResponseResult<StudentVo> queryUserById(String rongCloudUserId) {
+
+        if (StringUtil.isEmpty(rongCloudUserId)) {
+            return failed("用户信息获取失败");
+        }
+
+        Long userId = null;
+        String[] split = rongCloudUserId.split(":");
+        if (split.length == 2 && !StringUtil.isEmpty(split[0])) {
+            try {
+                userId = Long.parseLong(split[0]);
+            } catch (Exception e) {
+                e.printStackTrace();
+                return failed("用户信息获取失败");
+            }
+        }
+        return succeed(studentService.detail(userId));
+    }
+
     @ApiOperation(value = "查询学员")
     @GetMapping("/queryUser")
-    public HttpResponseResult<Student> queryUser() throws Exception {
+    public HttpResponseResult<Student> queryUser() {
         SysUser user = sysUserFeignService.queryUserInfo();
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");

+ 1 - 0
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/SysMusicCompareRecordController.java

@@ -75,6 +75,7 @@ public class SysMusicCompareRecordController extends BaseController {
         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")));

+ 1 - 1
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/config/ResourceServerConfig.java

@@ -32,7 +32,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                 .and()
                 .authorizeRequests()
                 .antMatchers("/task/*").hasIpAddress("0.0.0.0/0")
-                .antMatchers("/v2/api-docs", "/code/*",
+                .antMatchers("/v2/api-docs", "/code/*","/sysConfig/queryByParamNameList",
                         "/liveRoom/test", "/liveRoom/syncUserStatus", "/courseGroup/getLockCache", "/open/**",
                         "/liveRoomVideo/recordSync"
                 ).permitAll().anyRequest().authenticated().and().httpBasic();

+ 74 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicSheetController.java

@@ -1,10 +1,14 @@
 package com.yonge.cooleshow.teacher.controller;
 
+import com.yonge.cooleshow.biz.dal.dto.AppMusicSheetVo;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.enums.MusicSortType;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
 
+import java.util.ArrayList;
 import java.util.Date;
 
 import javax.validation.Valid;
@@ -110,6 +114,7 @@ public class MusicSheetController extends BaseController {
         musicSheetDto.setSubmitAuditTime(new Date());
         musicSheetDto.setSourceType(SourceTypeEnum.TEACHER);
 
+        musicSheetDto.setFavoriteCount(0);
         musicSheetDto.setCreateBy(sysUser.getId());
         musicSheetDto.setCreateTime(new Date());
         musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());
@@ -292,4 +297,73 @@ public class MusicSheetController extends BaseController {
         return succeed(PageUtil.pageInfo(musicSheetVoIPage));
     }
 
+
+    @ApiOperation(value = "app首页曲目数据", httpMethod="POST", consumes="application/json", produces="application/json")
+    @PostMapping(value="/appMusicSheet", consumes="application/json", produces="application/json")
+    public HttpResponseResult<AppMusicSheetVo> appMusicSheet(@RequestBody StudentMusicSheetSearch query) {
+        SysUser sysUser = sysUserFeignService.queryUserInfo();
+        if (sysUser == null  || sysUser.getId() == null) {
+            return failed("用户信息获取失败");
+        }
+
+        Teacher teacher = teacherService.getById(sysUser.getId());
+        if (teacher == null) {
+            return failed("用户信息获取失败");
+        }
+        if(StringUtils.isBlank(query.getSubjectIds())){
+            query.setSubjectIds(teacher.getSubjectId());
+        }
+
+        // 检查app版本
+        query.setAuditVersion(appVersionInfoService.getAppAuditVersion(query.getPlatform(),query.getVersion()));
+
+        //  只能看通过审核 并且 启用的 曲目
+        query.setState(YesOrNoEnum.YES);
+        query.setAuditStatus(AuthStatusEnum.PASS);
+        query.setStudentId(sysUser.getId());
+        query.setMyself(false);
+        query.setRows(20);
+
+        AppMusicSheetVo appMusicSheetVo = new AppMusicSheetVo();
+        // 推荐曲目
+        query.setMusicSortType(MusicSortType.TOP);
+        appMusicSheetVo.setTopMusicSheet(musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.TEACHER).getRecords());
+
+        // 审核版本只返回一列
+        if (query.getAuditVersion().equals(YesOrNoEnum.YES)) {
+            appMusicSheetVo.setHotMusicSheet(new ArrayList<>());
+            appMusicSheetVo.setNewMusicSheet(new ArrayList<>());
+        } else {
+            // 最热曲目
+            query.setMusicSortType(MusicSortType.HOT);
+            appMusicSheetVo.setHotMusicSheet(
+                    musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.STUDENT).getRecords());
+
+            // 最新曲目
+            query.setMusicSortType(MusicSortType.NEW);
+            appMusicSheetVo.setNewMusicSheet(
+                    musicSheetService.selectStudentPage(PageUtil.getPage(query), query, ClientEnum.STUDENT).getRecords());
+        }
+        return succeed(appMusicSheetVo);
+    }
+
+
+    /**
+     * 最近练习
+     */
+    @GetMapping("/user/practice")
+    @ApiOperation(value = "老师查看学生最近练习")
+    public HttpResponseResult<PageInfo<MusicSheetVo>> practiceMusic(@RequestParam Long userId) {
+
+        if (userId == null) {
+            return failed("用户信息不存在");
+        }
+        StudentMusicSheetSearch search = new StudentMusicSheetSearch();
+        search.setStudentId(userId);
+        search.setState(YesOrNoEnum.YES);
+        search.setAuditStatus(AuthStatusEnum.PASS);
+        search.setRows(3);
+        IPage<MusicSheetVo> sheetVoIPage = musicSheetService.practiceMusic(PageUtil.getPage(search),search);
+        return succeed(PageUtil.pageInfo(sheetVoIPage));
+    }
 }

+ 2 - 2
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/MusicTagController.java

@@ -26,8 +26,8 @@ public class MusicTagController extends BaseController {
 	 */
 	@GetMapping("/tree")
 	@ApiOperation(value = "查询标签树列表")
-	public HttpResponseResult<List<MusicTagVo>> tree() {
-		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree();
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
 		return succeed(treeList);
 	}
 

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

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

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

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

+ 9 - 0
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/open/OpenShareController.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.teacher.controller.open;
 
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.biz.dal.dto.MusicImgDto;
 import com.yonge.cooleshow.biz.dal.dto.search.ShareProfitParam;
 import com.yonge.cooleshow.biz.dal.entity.SysConfig;
 import com.yonge.cooleshow.biz.dal.service.*;
@@ -51,6 +52,14 @@ public class OpenShareController extends BaseController {
     @Autowired
     private MusicAlbumService musicAlbumService;
 
+
+
+    @ApiOperation(value = "新增曲谱渲染图")
+    @PostMapping(value="/music/sheet/img")
+    public HttpResponseResult<Boolean> img(@RequestBody @Valid MusicImgDto musicImgDto) {
+        return succeed(musicSheetService.updateMusicImg(musicImgDto.getMusicImg(),musicImgDto.getMusicSheetId()));
+    }
+
     /**
      * 服务对象
      */

+ 1 - 1
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/config/ResourceServerConfig.java

@@ -31,7 +31,7 @@ public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
                 .and()
                 .authorizeRequests()
                 .antMatchers("/task/*").hasIpAddress("0.0.0.0/0")
-                .antMatchers("/v2/api-docs", "/code/*",
+                .antMatchers("/v2/api-docs", "/code/*","/sysConfig/queryByParamNameList",
                         "/liveRoom/test", "/liveRoom/syncUserStatus", "/courseGroup/getLockCache", "/open/**")
                 .permitAll().anyRequest().authenticated().and().httpBasic();
     }

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

@@ -179,6 +179,7 @@ public class MusicSheetController extends BaseController {
         musicSheetDto.setSubmitAuditTime(new Date());
         musicSheetDto.setSourceType(SourceTypeEnum.TEACHER);
 
+        musicSheetDto.setFavoriteCount(0);
         musicSheetDto.setCreateBy(sysUser.getId());
         musicSheetDto.setCreateTime(new Date());
         musicSheetService.saveMusicSheet(musicSheetDto,sysUser.getId());

+ 2 - 2
cooleshow-user/user-website/src/main/java/com/yonge/cooleshow/website/controller/open/OpenMusicTagController.java

@@ -26,8 +26,8 @@ public class OpenMusicTagController extends BaseController {
 	 */
 	@GetMapping("/tree")
 	@ApiOperation(value = "查询标签树列表")
-	public HttpResponseResult<List<MusicTagVo>> tree() {
-		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree();
+	public HttpResponseResult<List<MusicTagVo>> tree(String type) {
+		List<MusicTagVo> treeList = musicTagService.selectMusicTagTree(type);
 		return succeed(treeList);
 	}
 

+ 15 - 0
service.md

@@ -0,0 +1,15 @@
+- [ ] gateway-server
+- [ ] auth-server
+- [x] admin-server
+- [ ] teacher-server
+- [ ] student-server
+- [ ] website-server
+- [ ] task-server
+- [ ] websocket-server
+- [ ] audio-analysis
+- [ ] bbs-server
+- [ ] classroom-server
+- [ ] cms-server
+- [ ] mall-admin
+- [ ] mall-server
+- [ ] EOF