|
@@ -175,29 +175,40 @@ public class itemApiController {
|
|
|
@Autowired
|
|
|
private ItemService itemService;
|
|
|
|
|
|
- /**
|
|
|
- * 专辑详情页面渲染所需要数据
|
|
|
- * @param albumId
|
|
|
- * @return
|
|
|
- */
|
|
|
- @Operation(summary = "专辑详情页面渲染所需要数据")
|
|
|
- @GetMapping("/albumInfo/{albumId}")
|
|
|
- public Result<Map<String, Object>> getItemData(@PathVariable Long albumId){
|
|
|
- Map<String, Object> map = itemService.getItemData(albumId);
|
|
|
- return Result.ok(map);
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 根据专辑ID汇总详情页所需参数
|
|
|
+ *
|
|
|
+ * @param albumId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @Operation(summary = "根据专辑ID汇总详情页所需参数")
|
|
|
+ @GetMapping("/albumInfo/{albumId}")
|
|
|
+ public Result<Map<String, Object>> getItem(@PathVariable Long albumId) {
|
|
|
+ Map<String, Object> map = itemService.getItem(albumId);
|
|
|
+ return Result.ok(map);
|
|
|
+ }
|
|
|
}
|
|
|
```
|
|
|
|
|
|
接口与实现
|
|
|
|
|
|
```java
|
|
|
-/**
|
|
|
- * 专辑详情页面渲染所需要数据
|
|
|
- * @param albumId
|
|
|
- * @return
|
|
|
- */
|
|
|
-Map<String, Object> getItemData(Long albumId);
|
|
|
+package com.atguigu.tingshu.search.service;
|
|
|
+
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public interface ItemService {
|
|
|
+ /**
|
|
|
+ * 根据专辑ID汇总详情页所需参数
|
|
|
+ *
|
|
|
+ * @param albumId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ //ItemVo getItem(Long albumId);
|
|
|
+
|
|
|
+ Map<String, Object> getItem(Long albumId);
|
|
|
+}
|
|
|
+
|
|
|
```
|
|
|
|
|
|
|
|
@@ -236,56 +247,65 @@ public class ItemServiceImpl implements ItemService {
|
|
|
private UserFeignClient userFeignClient;
|
|
|
|
|
|
@Autowired
|
|
|
- private Executor threadPoolTaskExecutor;
|
|
|
+ @Qualifier("threadPoolTaskExecutor")
|
|
|
+ private Executor executor;
|
|
|
|
|
|
/**
|
|
|
- * 专辑详情页面渲染所需要数据
|
|
|
+ * 根据专辑ID汇总详情页所需参数
|
|
|
*
|
|
|
* @param albumId
|
|
|
- * @return {albumInfo:{},baseCategoryView:{},announcer:{},albumStatVo:{}}
|
|
|
+ * @return
|
|
|
*/
|
|
|
@Override
|
|
|
- public Map<String, Object> getItemData(Long albumId) {
|
|
|
- //1.TODO 根据专辑ID查询布隆过滤器判断专辑是否存在-解决缓存传统问题
|
|
|
- //注意:引入多线程异步任务优化后,存在多线程并发写hashmap(线程不安全)改为线程安全:ConcurrentHashMap
|
|
|
+ public Map<String, Object> getItem(Long albumId) {
|
|
|
+ //0.TODO 采用布隆过滤器解决缓存穿透问题
|
|
|
+
|
|
|
+ //1.创建Map对象用于封装详情页数据
|
|
|
Map<String, Object> map = new ConcurrentHashMap<>();
|
|
|
- //2.远程调用专辑服务获取专辑信息
|
|
|
+
|
|
|
+ //2.远程调用专辑服务:根据专辑ID查询专辑信息
|
|
|
CompletableFuture<AlbumInfo> albumInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
|
|
|
+ log.info("获取专辑信息异步任务:{}", albumId);
|
|
|
AlbumInfo albumInfo = albumFeignClient.getAlbumInfo(albumId).getData();
|
|
|
- Assert.notNull(albumInfo, "专辑:{}不存在!", albumId);
|
|
|
+ Assert.notNull(albumInfo, "专辑{}不存在", albumId);
|
|
|
map.put("albumInfo", albumInfo);
|
|
|
return albumInfo;
|
|
|
- }, threadPoolTaskExecutor);
|
|
|
+ }, executor);
|
|
|
+
|
|
|
+ //3.远程调用专辑服务:根据专辑所属分类ID查询分类信息
|
|
|
+ CompletableFuture<Void> baseCategoryCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
|
|
|
+ BaseCategoryView categoryView = albumFeignClient.getCategoryView(albumInfo.getCategory3Id()).getData();
|
|
|
+ Assert.notNull(categoryView, "分类{}不存在", albumInfo.getCategory3Id());
|
|
|
+ map.put("baseCategoryView", categoryView);
|
|
|
+ }, executor);
|
|
|
|
|
|
- //3.远程调用专辑服务获取分类信息
|
|
|
- CompletableFuture<Void> baseCategoryViewCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
|
|
|
- BaseCategoryView baseCategoryView = albumFeignClient.getCategoryView(albumInfo.getCategory3Id()).getData();
|
|
|
- Assert.notNull(baseCategoryView, "分类:{}不存在!", albumInfo.getCategory3Id());
|
|
|
- map.put("baseCategoryView", baseCategoryView);
|
|
|
- }, threadPoolTaskExecutor);
|
|
|
|
|
|
- //4.远程调用用户服务获取主播信息
|
|
|
+ //4.远程调用用户服务:根据专辑所属主播ID查询主播信息
|
|
|
CompletableFuture<Void> announcerCompletableFuture = albumInfoCompletableFuture.thenAcceptAsync(albumInfo -> {
|
|
|
UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(albumInfo.getUserId()).getData();
|
|
|
- Assert.notNull(userInfoVo, "主播:{}不存在!", albumInfo.getUserId());
|
|
|
+ Assert.notNull(userInfoVo, "用户{}不存在", albumInfo.getUserId());
|
|
|
map.put("announcer", userInfoVo);
|
|
|
- }, threadPoolTaskExecutor);
|
|
|
+ }, executor);
|
|
|
|
|
|
- //4.远程调用专辑服务获取统计信息
|
|
|
+ //5.远程调用专辑服务:根据专辑ID查询专辑统计信息
|
|
|
CompletableFuture<Void> albumStatVoCompletableFuture = CompletableFuture.runAsync(() -> {
|
|
|
+ log.info("获取专辑统计异步任务:{}", albumId);
|
|
|
AlbumStatVo albumStatVo = albumFeignClient.getAlbumStatVo(albumId).getData();
|
|
|
- Assert.notNull(albumStatVo, "专辑统计:{}不存在!", albumId);
|
|
|
+ Assert.notNull(albumStatVo, "专辑统计{}不存在", albumId);
|
|
|
map.put("albumStatVo", albumStatVo);
|
|
|
- }, threadPoolTaskExecutor);
|
|
|
+ }, executor);
|
|
|
|
|
|
- //5.汇总异步任务
|
|
|
- CompletableFuture.allOf(
|
|
|
- albumInfoCompletableFuture,
|
|
|
- albumStatVoCompletableFuture,
|
|
|
- baseCategoryViewCompletableFuture,
|
|
|
- announcerCompletableFuture
|
|
|
- ).join();
|
|
|
|
|
|
+ //6.组合异步任务
|
|
|
+ CompletableFuture.allOf(
|
|
|
+ albumInfoCompletableFuture,
|
|
|
+ baseCategoryCompletableFuture,
|
|
|
+ announcerCompletableFuture,
|
|
|
+ albumStatVoCompletableFuture
|
|
|
+ ).orTimeout(1, TimeUnit.SECONDS)
|
|
|
+ .join();
|
|
|
+
|
|
|
+ //7.响应Map对象
|
|
|
return map;
|
|
|
}
|
|
|
}
|
|
@@ -330,22 +350,21 @@ public class ItemServiceImpl implements ItemService {
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * 检查提交声音ID列表购买情况
|
|
|
- *
|
|
|
- * @param userId 用户ID
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param needCheckBuyStateTrackIds 待检查购买情况声音ID列表
|
|
|
- * @return 提交待检查购买声音ID购买结果 {38679:1,38678:0}
|
|
|
+ * 提交需要检查购买状态声音ID列表,响应每个声音购买状态
|
|
|
+ * @param userId
|
|
|
+ * @param albumId
|
|
|
+ * @param needCheckPayStatusTrackIdList 待检查购买状态声音ID列表
|
|
|
+ * @return
|
|
|
*/
|
|
|
-@Operation(summary = "检查提交声音ID列表购买情况")
|
|
|
+@Operation(summary = "提交需要检查购买状态声音ID列表,响应每个声音购买状态")
|
|
|
@PostMapping("/userInfo/userIsPaidTrack/{userId}/{albumId}")
|
|
|
public Result<Map<Long, Integer>> userIsPaidTrack(
|
|
|
- @PathVariable Long userId,
|
|
|
- @PathVariable Long albumId,
|
|
|
- @RequestBody List<Long> needCheckBuyStateTrackIds
|
|
|
-) {
|
|
|
- Map<Long, Integer> map = userInfoService.userIsPaidTrack(userId, albumId, needCheckBuyStateTrackIds);
|
|
|
- return Result.ok(map);
|
|
|
+ @PathVariable Long userId,
|
|
|
+ @PathVariable Long albumId,
|
|
|
+ @RequestBody List<Long> needCheckPayStatusTrackIdList
|
|
|
+ ) {
|
|
|
+ Map<Long, Integer> map = userInfoService.userIsPaidTrack(userId, albumId, needCheckPayStatusTrackIdList);
|
|
|
+ return Result.ok(map);
|
|
|
}
|
|
|
```
|
|
|
|
|
@@ -353,71 +372,69 @@ public Result<Map<Long, Integer>> userIsPaidTrack(
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * 检查提交声音ID列表购买情况
|
|
|
+ * 提交需要检查购买状态声音ID列表,响应每个声音购买状态
|
|
|
*
|
|
|
- * @param userId 用户ID
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param needCheckBuyStateTrackIds 待检查购买情况声音ID列表
|
|
|
- * @return 提交待检查购买声音ID购买结果 {38679:1,38678:0}
|
|
|
+ * @param userId
|
|
|
+ * @param albumId
|
|
|
+ * @param needCheckPayStatusTrackIdList
|
|
|
+ * @return
|
|
|
*/
|
|
|
-Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckBuyStateTrackIds);
|
|
|
+Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckPayStatusTrackIdList);
|
|
|
```
|
|
|
|
|
|
**UserInfoServiceImpl实现类**:
|
|
|
|
|
|
```java
|
|
|
-@Autowired
|
|
|
-private UserPaidAlbumMapper userPaidAlbumMapper;
|
|
|
-
|
|
|
-@Autowired
|
|
|
-private UserPaidTrackMapper userPaidTrackMapper;
|
|
|
-
|
|
|
/**
|
|
|
- * 检查提交声音ID列表购买情况
|
|
|
+ * 提交需要检查购买状态声音ID列表,响应每个声音购买状态
|
|
|
*
|
|
|
- * @param userId 用户ID
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param needCheckBuyStateTrackIds 待检查购买情况声音ID列表
|
|
|
- * @return 提交待检查购买情况,声音ID购买结果 {38679:1,38678:0}
|
|
|
+ * @param userId 用户ID
|
|
|
+ * @param albumId 专辑ID
|
|
|
+ * @param needCheckPayStatusTrackIdList 待检查购买状态声音ID列表
|
|
|
+ * @return
|
|
|
*/
|
|
|
@Override
|
|
|
-public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckBuyStateTrackIds) {
|
|
|
+public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckPayStatusTrackIdList) {
|
|
|
Map<Long, Integer> map = new HashMap<>();
|
|
|
//1.根据用户ID+专辑ID查询专辑购买记录
|
|
|
- LambdaQueryWrapper<UserPaidAlbum> userPaidAlbumLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getAlbumId, albumId);
|
|
|
- userPaidAlbumLambdaQueryWrapper.eq(UserPaidAlbum::getUserId, userId);
|
|
|
- Long count = userPaidAlbumMapper.selectCount(userPaidAlbumLambdaQueryWrapper);
|
|
|
- //1.1 存在购买记录
|
|
|
+ Long count = userPaidAlbumMapper.selectCount(
|
|
|
+ new LambdaQueryWrapper<UserPaidAlbum>()
|
|
|
+ .eq(UserPaidAlbum::getUserId, userId)
|
|
|
+ .eq(UserPaidAlbum::getAlbumId, albumId)
|
|
|
+ );
|
|
|
+
|
|
|
+ //2. 如果已购买专辑,将所有待检查购买状态声音 购买状态设置为 1 响应
|
|
|
if (count > 0) {
|
|
|
- for (Long needCheckBuyStateTrackId : needCheckBuyStateTrackIds) {
|
|
|
- //1.1 将所有提交待检查声音ID购买情况设置1
|
|
|
- map.put(needCheckBuyStateTrackId, 1);
|
|
|
+ for (Long trackId : needCheckPayStatusTrackIdList) {
|
|
|
+ map.put(trackId, 1);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
|
|
|
- //2.根据用户ID+专辑ID查询已购声音表
|
|
|
- LambdaQueryWrapper<UserPaidTrack> userPaidTrackLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getUserId, userId);
|
|
|
- userPaidTrackLambdaQueryWrapper.eq(UserPaidTrack::getAlbumId, albumId);
|
|
|
- userPaidTrackLambdaQueryWrapper.select(UserPaidTrack::getTrackId);
|
|
|
- List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(userPaidTrackLambdaQueryWrapper);
|
|
|
- if (CollectionUtil.isEmpty(userPaidTrackList)) {
|
|
|
- //2.1 如果不存在已购声音 将所有提交待检查声音ID购买情况设置0返回
|
|
|
- for (Long needCheckBuyStateTrackId : needCheckBuyStateTrackIds) {
|
|
|
- map.put(needCheckBuyStateTrackId, 0);
|
|
|
+ //3. 根据用户ID+专辑ID查询已购声音记录
|
|
|
+ List<UserPaidTrack> userPaidTrackList = userPaidTrackMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<UserPaidTrack>()
|
|
|
+ .eq(UserPaidTrack::getUserId, userId)
|
|
|
+ .eq(UserPaidTrack::getAlbumId, albumId)
|
|
|
+ .select(UserPaidTrack::getTrackId)
|
|
|
+ );
|
|
|
+
|
|
|
+ //4. 如果不存再已购声音,将所有待检查购买状态声音 购买状态设置为 0 响应
|
|
|
+ if (CollUtil.isEmpty(userPaidTrackList)) {
|
|
|
+ for (Long trackId : needCheckPayStatusTrackIdList) {
|
|
|
+ map.put(trackId, 0);
|
|
|
}
|
|
|
return map;
|
|
|
}
|
|
|
- //2.2 存在已购声音,遍历待检查声音ID列表判断找出已购声音购买情况设置1,未购买声音购买情况设置为0
|
|
|
+
|
|
|
+
|
|
|
+ //5.如果存在已购声音,将提交检查声音ID列表中,已购声购买状态设置为:1。未购买设置为0
|
|
|
List<Long> userPaidTrackIdList = userPaidTrackList.stream().map(UserPaidTrack::getTrackId).collect(Collectors.toList());
|
|
|
- for (Long needCheckBuyStateTrackId : needCheckBuyStateTrackIds) {
|
|
|
- //判断已购声音ID列表中是否存在待检查声音ID
|
|
|
- if(userPaidTrackIdList.contains(needCheckBuyStateTrackId)){
|
|
|
- map.put(needCheckBuyStateTrackId, 1);
|
|
|
- }else{
|
|
|
- map.put(needCheckBuyStateTrackId, 0);
|
|
|
+ for (Long trackId : needCheckPayStatusTrackIdList) {
|
|
|
+ if (userPaidTrackIdList.contains(trackId)) {
|
|
|
+ map.put(trackId, 1);
|
|
|
+ } else {
|
|
|
+ map.put(trackId, 0);
|
|
|
}
|
|
|
}
|
|
|
return map;
|
|
@@ -428,18 +445,17 @@ public Map<Long, Integer> userIsPaidTrack(Long userId, Long albumId, List<Long>
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * 检查提交声音ID列表购买情况
|
|
|
- *
|
|
|
- * @param userId 用户ID
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param needCheckBuyStateTrackIds 待检查购买情况声音ID列表
|
|
|
- * @return 提交待检查购买声音ID购买结果 {38679:1,38678:0}
|
|
|
+ * 提交需要检查购买状态声音ID列表,响应每个声音购买状态
|
|
|
+ * @param userId
|
|
|
+ * @param albumId
|
|
|
+ * @param needCheckPayStatusTrackIdList 待检查购买状态声音ID列表
|
|
|
+ * @return
|
|
|
*/
|
|
|
@PostMapping("/userInfo/userIsPaidTrack/{userId}/{albumId}")
|
|
|
public Result<Map<Long, Integer>> userIsPaidTrack(
|
|
|
@PathVariable Long userId,
|
|
|
@PathVariable Long albumId,
|
|
|
- @RequestBody List<Long> needCheckBuyStateTrackIds
|
|
|
+ @RequestBody List<Long> needCheckPayStatusTrackIdList
|
|
|
);
|
|
|
```
|
|
|
|
|
@@ -447,8 +463,8 @@ public Result<Map<Long, Integer>> userIsPaidTrack(
|
|
|
|
|
|
```java
|
|
|
@Override
|
|
|
-public Result<Map<Long, Integer>> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckBuyStateTrackIds) {
|
|
|
- log.error("[用户服务]远程调用userIsPaidTrack执行服务降级");
|
|
|
+public Result<Map<Long, Integer>> userIsPaidTrack(Long userId, Long albumId, List<Long> needCheckPayStatusTrackIdList) {
|
|
|
+ log.error("【用户服务】提供userIsPaidTrack远程调用失败");
|
|
|
return null;
|
|
|
}
|
|
|
```
|
|
@@ -463,27 +479,30 @@ public Result<Map<Long, Integer>> userIsPaidTrack(Long userId, Long albumId, Lis
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * TODO 该方法不登录可以访问,但用户登录状态就可以从ThreadLocal获取用户ID
|
|
|
- * 分页查询当前用户可见声音列表-动态判断声音付费标识
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param page 页码
|
|
|
- * @param limit 页大小
|
|
|
+ * 需求:用户未登录,可以给用户展示声音列表;用户已登录,可以给用户展示声音列表,并动态渲染付费标识
|
|
|
+ * 分页查询专辑下声音列表(动态渲染付费标识)
|
|
|
+ *
|
|
|
+ * @param albumId
|
|
|
+ * @param page
|
|
|
+ * @param limit
|
|
|
* @return
|
|
|
*/
|
|
|
@GuiGuLogin(required = false)
|
|
|
-@Operation(summary = "分页查询当前用户可见声音列表-动态判断声音付费标识")
|
|
|
+@Operation(summary = "分页查询专辑下声音列表(动态渲染付费标识)")
|
|
|
@GetMapping("/trackInfo/findAlbumTrackPage/{albumId}/{page}/{limit}")
|
|
|
-public Result<Page<AlbumTrackListVo>> getAlbumTrackPage(
|
|
|
+public Result<IPage<AlbumTrackListVo>> findAlbumTrackPage(
|
|
|
@PathVariable Long albumId,
|
|
|
- @PathVariable int page,
|
|
|
- @PathVariable int limit
|
|
|
-){
|
|
|
- //1.获取当前登录用户信息
|
|
|
+ @PathVariable Long page,
|
|
|
+ @PathVariable Long limit) {
|
|
|
+ //1.尝试获取用户ID
|
|
|
Long userId = AuthContextHolder.getUserId();
|
|
|
- //2.构建分页所需Page对象
|
|
|
- Page<AlbumTrackListVo> pageInfo = new Page<>(page, limit);
|
|
|
- //3.调用业务层获取业务数据
|
|
|
- pageInfo = trackInfoService.getAlbumTrackPage(pageInfo, albumId, userId);
|
|
|
+ //2.构建分页对象:封装当前页码、每页记录数
|
|
|
+ IPage<AlbumTrackListVo> pageInfo = new Page<>(page, limit);
|
|
|
+
|
|
|
+ //3.调用业务逻辑层->持久层:封装:总记录数,总页数,当前页数据
|
|
|
+ pageInfo = trackInfoService.findAlbumTrackPage(pageInfo, albumId, userId);
|
|
|
+
|
|
|
+ //4.响应分页对象
|
|
|
return Result.ok(pageInfo);
|
|
|
}
|
|
|
```
|
|
@@ -492,13 +511,15 @@ public Result<Page<AlbumTrackListVo>> getAlbumTrackPage(
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * 分页查询当前用户可见声音列表-动态判断声音付费标识
|
|
|
- * @param pageInfo 分页对象
|
|
|
- * @param albumId 专辑ID
|
|
|
- * @param userId 用户ID
|
|
|
- * @return
|
|
|
- */
|
|
|
-Page<AlbumTrackListVo> getAlbumTrackPage(Page<AlbumTrackListVo> pageInfo, Long albumId, Long userId);
|
|
|
+* 需求:用户未登录,可以给用户展示声音列表;用户已登录,可以给用户展示声音列表,并动态渲染付费标识
|
|
|
+* 分页查询专辑下声音列表(动态渲染付费标识)
|
|
|
+*
|
|
|
+* @param pageInfo MP分页对象
|
|
|
+* @param albumId 专辑ID
|
|
|
+* @param userId 用户ID
|
|
|
+* @return
|
|
|
+*/
|
|
|
+IPage<AlbumTrackListVo> findAlbumTrackPage(IPage<AlbumTrackListVo> pageInfo, Long albumId, Long userId);
|
|
|
```
|
|
|
|
|
|
**TrackInfoServiceImpl实现类:**
|
|
@@ -524,77 +545,77 @@ Page<AlbumTrackListVo> getAlbumTrackPage(Page<AlbumTrackListVo> pageInfo, Long a
|
|
|
@Autowired
|
|
|
private UserFeignClient userFeignClient;
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
- * 分页查询当前用户可见声音列表-动态判断声音付费标识
|
|
|
+ * 需求:用户未登录,可以给用户展示声音列表;用户已登录,可以给用户展示声音列表,并动态渲染付费标识
|
|
|
+ * 分页查询专辑下声音列表(动态渲染付费标识)
|
|
|
*
|
|
|
- * @param pageInfo 分页对象
|
|
|
+ * @param pageInfo MP分页对象
|
|
|
* @param albumId 专辑ID
|
|
|
* @param userId 用户ID
|
|
|
* @return
|
|
|
*/
|
|
|
@Override
|
|
|
-public Page<AlbumTrackListVo> getAlbumTrackPage(Page<AlbumTrackListVo> pageInfo, Long albumId, Long userId) {
|
|
|
- //1.分页查询专辑下声音列表 TODO 暂不考虑声音付费标识 默认Vo对象AlbumTrackListVo付费标识:false
|
|
|
- pageInfo = trackInfoMapper.getAlbumTrackPage(pageInfo, albumId);
|
|
|
+public IPage<AlbumTrackListVo> findAlbumTrackPage(IPage<AlbumTrackListVo> pageInfo, Long albumId, Long userId) {
|
|
|
+ //1.分页获取声音列表(包含统计数值) isShowPaidMark默认为false
|
|
|
+ pageInfo = trackInfoMapper.findAlbumTrackPage(pageInfo, albumId);
|
|
|
|
|
|
- //2.根据专辑ID查询专辑信息.得到付费类型,试听集数
|
|
|
+ //动态渲染付费标识
|
|
|
+ //2.根据专辑ID查询专辑信息,得到专辑付费类型以及免费试听的集数
|
|
|
AlbumInfo albumInfo = albumInfoMapper.selectById(albumId);
|
|
|
- //2.1 付费类型: 0101-免费、0102-vip免费、0103-付费
|
|
|
+ Assert.notNull(albumInfo, "专辑{}不存在", albumId);
|
|
|
+ //2.1 付费类型:0101-免费、0102-vip免费、0103-付费
|
|
|
String payType = albumInfo.getPayType();
|
|
|
- //2.2 获取当前专辑免费试听集数
|
|
|
+ //2.2 免费实体集数
|
|
|
Integer tracksForFree = albumInfo.getTracksForFree();
|
|
|
-
|
|
|
- //3.判断用户未登录情况
|
|
|
+ //3.如果用户未登录 情况一:且专辑付费类型是:VIP免费或付费,将除试听以外其他声音付费标识设置true
|
|
|
if (userId == null) {
|
|
|
- //3.1 专辑付费类型:VIP免费或付费
|
|
|
- if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType) || SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {
|
|
|
- //3.2 除去试听其他声音将付费标识全部设置true
|
|
|
+ if (ALBUM_PAY_TYPE_VIPFREE.equals(payType) || ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {
|
|
|
pageInfo.getRecords()
|
|
|
.stream()
|
|
|
- .filter(vo -> vo.getOrderNum() > tracksForFree)
|
|
|
- .forEach(vo -> vo.setIsShowPaidMark(true));
|
|
|
+ .filter(t -> t.getOrderNum() > tracksForFree)
|
|
|
+ .forEach(t -> t.setIsShowPaidMark(true));
|
|
|
}
|
|
|
} else {
|
|
|
- //4.判断用户已登录情况
|
|
|
- //4.1 远程调用用户服务获取用户信息:是否VIP用户
|
|
|
+ //4. 如果用户已登录 满足以下两种情况需要进一步获取当前页声音购买状态
|
|
|
+ //4.1 远程调用用户服务获取用户身份,判断是否为会员(有效期内会员)
|
|
|
UserInfoVo userInfoVo = userFeignClient.getUserInfoVo(userId).getData();
|
|
|
- Assert.notNull(userInfoVo, "用户:{}不存在!", userId);
|
|
|
+ Assert.notNull(userInfoVo, "用户{}不存在", userId);
|
|
|
Boolean isVIP = false;
|
|
|
- if (1 == userInfoVo.getIsVip().intValue() && userInfoVo.getVipExpireTime().after(new Date())) {
|
|
|
- //会员标识必须是1,且会员过期时间大于当前系统时间
|
|
|
+ if (userInfoVo.getIsVip().intValue() == 1 && userInfoVo.getVipExpireTime().after(new Date())) {
|
|
|
isVIP = true;
|
|
|
}
|
|
|
- Boolean isNeedCheck = false;
|
|
|
- //4.2 判断专辑付费类型=VIP免费 当前用户是普通用户,都需要进一步判断声音购买情况
|
|
|
- if (SystemConstant.ALBUM_PAY_TYPE_VIPFREE.equals(payType) && !isVIP) {
|
|
|
- isNeedCheck = true;
|
|
|
+
|
|
|
+ //4.2 情况二:如果专辑 付费类型:VIP免费 且 当前用户是普通用户,满足进一步查询当前页声音购买状态
|
|
|
+ Boolean isNeedCheckPayStatus = false;
|
|
|
+ if (!isVIP && ALBUM_PAY_TYPE_VIPFREE.equals(payType)) {
|
|
|
+ isNeedCheckPayStatus = true;
|
|
|
}
|
|
|
- //4.3 判断专辑付费类型=付费 所有用户都需要进一步判断声音购买情况
|
|
|
- if (SystemConstant.ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {
|
|
|
- isNeedCheck = true;
|
|
|
+ //4.3 情况三:如果专辑 付费类型:付费,无论什么用户,满足进一步查询当前页声音购买状态
|
|
|
+ if (ALBUM_PAY_TYPE_REQUIRE.equals(payType)) {
|
|
|
+ isNeedCheckPayStatus = true;
|
|
|
}
|
|
|
- //4.4 远程调用用户服务获取本页中所有声音购买情况
|
|
|
- if (isNeedCheck) {
|
|
|
- //4.4.1 获取本页中需要检查购买情况声音(去掉免费试听)
|
|
|
- List<Long> needCheckBuyStateTrackIds =
|
|
|
- pageInfo.getRecords()
|
|
|
- .stream()
|
|
|
- .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
|
|
|
- .map(AlbumTrackListVo::getTrackId)
|
|
|
- .collect(Collectors.toList());
|
|
|
- //4.4.1 根据用户ID+专辑ID+本页中声音ID列表,远程调用用户服务检查声音购买情况
|
|
|
- Map<Long, Integer> buyStateMap = userFeignClient.userIsPaidTrack(userId, albumId, needCheckBuyStateTrackIds).getData();
|
|
|
-
|
|
|
- //4.5 根据本页中购买情况:如果声音购买状态为未购买(0)将付费标识改为:true
|
|
|
- pageInfo.getRecords()
|
|
|
+
|
|
|
+ //4.4 如果满足情况二或情况三,远程调用用户服务,得到当前页除试听部分每个声音购买状态
|
|
|
+ if (isNeedCheckPayStatus) {
|
|
|
+ //4.4.1 获取当前页中除试听以外其他声音ID列表
|
|
|
+ List<Long> needCheckPayStatusTrackIdList = pageInfo
|
|
|
+ .getRecords()
|
|
|
+ .stream()
|
|
|
+ .filter(t -> t.getOrderNum() > tracksForFree)
|
|
|
+ .map(AlbumTrackListVo::getTrackId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ //4.4.2 远程调用用户服务,获取当前页中声音购买状态Map<Long-专辑ID,Integer-购买状态>
|
|
|
+ Map<Long, Integer> payStatusMap =
|
|
|
+ userFeignClient.userIsPaidTrack(userId, albumId, needCheckPayStatusTrackIdList).getData();
|
|
|
+
|
|
|
+ //4.5 根据响应声音购买状态,动态修改付费标识。购买状态为0的声音付费标识isShowPaidMark全部设置:true
|
|
|
+ pageInfo
|
|
|
+ .getRecords()
|
|
|
.stream()
|
|
|
- .filter(albumTrackListVo -> albumTrackListVo.getOrderNum() > tracksForFree)
|
|
|
- .forEach(albumTrackListVo -> {
|
|
|
- //如果声音ID未购买,将付费标识设置true
|
|
|
- if (buyStateMap.get(albumTrackListVo.getTrackId()).intValue() == 0) {
|
|
|
- albumTrackListVo.setIsShowPaidMark(true);
|
|
|
- }
|
|
|
- });
|
|
|
+ .filter(t -> t.getOrderNum() > tracksForFree)
|
|
|
+ .forEach(t -> t.setIsShowPaidMark(payStatusMap.get(t.getTrackId()) == 0));
|
|
|
}
|
|
|
}
|
|
|
return pageInfo;
|
|
@@ -605,12 +626,12 @@ public Page<AlbumTrackListVo> getAlbumTrackPage(Page<AlbumTrackListVo> pageInfo,
|
|
|
|
|
|
```java
|
|
|
/**
|
|
|
- * 分页展示专辑下声音列表
|
|
|
- * @param pageInfo 分页对象 MP会自动进行分页
|
|
|
- * @param albumId 专辑ID
|
|
|
+ * 分页获取声音列表(包含统计数值)
|
|
|
+ * @param pageInfo 分页对象,框架自动SQL后面拼接limit部分
|
|
|
+ * @param albumId
|
|
|
* @return
|
|
|
*/
|
|
|
-Page<AlbumTrackListVo> getAlbumTrackPage(Page<AlbumTrackListVo> pageInfo, @Param("albumId") Long albumId);
|
|
|
+IPage<AlbumTrackListVo> findAlbumTrackPage(IPage<AlbumTrackListVo> pageInfo, @Param("albumId") Long albumId);
|
|
|
```
|
|
|
|
|
|
**TrackInfoMapper.xml** 映射文件
|
|
@@ -636,19 +657,20 @@ limit 0,10;
|
|
|
```
|
|
|
|
|
|
```sql
|
|
|
-<!--分页查询当前专辑下包含声音列表-->
|
|
|
-<select id="getAlbumTrackPage" resultType="com.atguigu.tingshu.vo.album.AlbumTrackListVo">
|
|
|
+<!--分页获取声音列表(包含统计数值)-->
|
|
|
+<select id="findAlbumTrackPage" resultType="com.atguigu.tingshu.vo.album.AlbumTrackListVo">
|
|
|
select
|
|
|
- ti.id trackId,
|
|
|
+ ti.id as track_id,
|
|
|
ti.track_title,
|
|
|
ti.media_duration,
|
|
|
ti.order_num,
|
|
|
ti.create_time,
|
|
|
- max(if(stat_type='0701', stat_num, 0)) playStatNum,
|
|
|
- max(if(stat_type='0704', stat_num, 0)) commentStatNum
|
|
|
- from track_info ti inner join track_stat stat
|
|
|
- on stat.track_id = ti.id
|
|
|
- where ti.album_id = #{albumId} and ti.status = '0501' and ti.is_deleted = 0
|
|
|
+ max(if(stat.stat_type='0701', stat.stat_num, 0)) playStatNum,
|
|
|
+ max(if(stat.stat_type='0702', stat.stat_num, 0)) collectStatNum,
|
|
|
+ max(if(stat.stat_type='0703', stat.stat_num, 0)) praiseStatNum,
|
|
|
+ max(if(stat.stat_type='0704', stat.stat_num, 0)) commentStatNum
|
|
|
+ from track_info ti inner join track_stat stat on stat.track_id = ti.id and stat.is_deleted = 0
|
|
|
+ where album_id = #{albumId} and ti.status = '0501' and ti.is_deleted = 0
|
|
|
group by ti.id
|
|
|
order by ti.order_num asc
|
|
|
</select>
|