ソースを参照

Merge branch 'activity_v1.3.5_20220929'

# Conflicts:
#	cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityEvaluationRecordServiceImpl.java
Eric 3 年 前
コミット
09b0b19e44

+ 11 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ActivityPlanDao.java

@@ -4,6 +4,8 @@ import java.util.List;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
 import com.yonge.cooleshow.biz.dal.wrapper.StatGroupWrapper;
 import org.apache.ibatis.annotations.Param;
 import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
@@ -82,4 +84,13 @@ public interface ActivityPlanDao extends BaseMapper<ActivityPlan> {
 	 * @return List<StatGroupWrapper>
 	 */
 	List<StatGroupWrapper> selectActivityWinnerStatInfo(@Param("activityIds") List<Long> activityIds);
+
+	/**
+	 * 活动总分用户排名
+	 * @param activityId 活动ID
+	 * @param subjectId 声部ID
+	 * @return List<ActivityRankingVo>
+	 */
+    List<ActivityRankingVo> selectActivityHighestScoreRankingInfo(@Param("activityId") Long activityId, @Param("subjectId") Long subjectId,
+																  @Param("rankingScore") Double rankingScore, @Param("limit") Integer limit);
 }

+ 24 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/ActivityEvaluationRecord.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.yonge.cooleshow.biz.dal.enums.activity.ActivityRankingMethodEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -43,6 +44,14 @@ public class ActivityEvaluationRecord implements Serializable {
     @ApiModelProperty("次数")
     @TableField(value = "times_")
     private int times;
+
+    @ApiModelProperty("评份方式")
+    @TableField(value = "ranking_method_")
+    private ActivityRankingMethodEnum rankingMethod;
+
+    @ApiModelProperty("活动报名时间 ")
+    @TableField(value = "registration_time_")
+    private Long registrationTime;
     
     @ApiModelProperty("创建时间 ")
     @TableField(value = "create_time_")
@@ -114,4 +123,19 @@ public class ActivityEvaluationRecord implements Serializable {
         this.createTime = createTime;
     }
 
+    public ActivityRankingMethodEnum getRankingMethod() {
+        return rankingMethod;
+    }
+
+    public void setRankingMethod(ActivityRankingMethodEnum rankingMethod) {
+        this.rankingMethod = rankingMethod;
+    }
+
+    public Long getRegistrationTime() {
+        return registrationTime;
+    }
+
+    public void setRegistrationTime(Long registrationTime) {
+        this.registrationTime = registrationTime;
+    }
 }

+ 153 - 54
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/ActivityEvaluationRecordServiceImpl.java

@@ -1,6 +1,7 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.biz.dal.dao.ActivityEvaluationRecordDao;
@@ -8,88 +9,186 @@ import com.yonge.cooleshow.biz.dal.dto.search.ActivityEvaluationRecordSearch;
 import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluation;
 import com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord;
 import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
+import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
+import com.yonge.cooleshow.biz.dal.enums.activity.ActivityRankingMethodEnum;
 import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationRecordService;
 import com.yonge.cooleshow.biz.dal.service.ActivityEvaluationService;
 import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
+import com.yonge.cooleshow.biz.dal.service.MusicSheetService;
 import com.yonge.cooleshow.biz.dal.vo.ActivityEvaluationRecordVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
 import com.yonge.cooleshow.common.enums.ActivityResourceEnum;
 import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.base.util.ThreadPool;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections.CollectionUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
+import java.util.stream.Collectors;
 
+@Slf4j
 @Service
-public class ActivityEvaluationRecordServiceImpl
-    extends ServiceImpl<ActivityEvaluationRecordDao, ActivityEvaluationRecord>
-    implements ActivityEvaluationRecordService {
-  private final static Logger log =
-      LoggerFactory.getLogger(ActivityEvaluationRecordServiceImpl.class);
+public class ActivityEvaluationRecordServiceImpl extends ServiceImpl<ActivityEvaluationRecordDao, ActivityEvaluationRecord> implements ActivityEvaluationRecordService {
 
-  @Autowired private ActivityEvaluationService activityEvaluationService;
+    @Autowired
+    private ActivityEvaluationService activityEvaluationService;
+    @Autowired
+    private ActivityEvaluationRecordService activityEvaluationRecordService;
+    @Autowired
+    private ActivityPlanService activityPlanService;
+    @Autowired
+    private MusicSheetService musicSheetService;
 
-  @Autowired private ActivityPlanService activityPlanService;
+    @Override
+    public ActivityEvaluationRecordVo detail(Long id) {
+        return baseMapper.detail(id);
+    }
 
-  @Override
-  public ActivityEvaluationRecordVo detail(Long id) {
-    return baseMapper.detail(id);
-  }
+    @Override
+    public IPage<ActivityEvaluationRecordVo>
+    selectPage(IPage<ActivityEvaluationRecordVo> page,
+               ActivityEvaluationRecordSearch query) {
+        return page.setRecords(baseMapper.selectPage(page, query));
+    }
 
-  @Override
-  public IPage<ActivityEvaluationRecordVo>
-  selectPage(IPage<ActivityEvaluationRecordVo> page,
-             ActivityEvaluationRecordSearch query) {
-    return page.setRecords(baseMapper.selectPage(page, query));
-  }
+    @Override
+    public List<Long> getJoinEvaluationIdList(Long activityId, Long userId) {
+        return baseMapper.getJoinEvaluationIdList(activityId, userId);
+    }
 
-  @Override
-  public List<Long> getJoinEvaluationIdList(Long activityId, Long userId) {
-    return baseMapper.getJoinEvaluationIdList(activityId, userId);
-  }
+    @Override
+    public void saveRecord(Long evaluationId, Long userId, BigDecimal score) {
+        if (evaluationId == null) {
+            throw new BizException("评测项目id不能为空");
+        }
+        ActivityEvaluation activityEvaluation = activityEvaluationService.getById(evaluationId);
+        if (activityEvaluation == null) {
+            throw new BizException("未找到评测项目");
+        }
 
-  @Override
-  public void saveRecord(Long evaluationId, Long userId, BigDecimal score) {
-    if (evaluationId == null) {
-      throw new BizException("评测项目id不能为空");
-    }
-    ActivityEvaluation activityEvaluation =
-        activityEvaluationService.getById(evaluationId);
-    if (activityEvaluation == null) {
-      throw new BizException("未找到评测项目");
-    }
-    ActivityEvaluationRecord activityEvaluationRecord =
-        new ActivityEvaluationRecord();
-    activityEvaluationRecord.setActivityId(activityEvaluation.getActivityId());
-    activityEvaluationRecord.setUserId(userId);
-    activityEvaluationRecord.setEvaluationId(evaluationId);
-    activityEvaluationRecord.setCreateTime(new Date());
-    activityEvaluationRecord.setScore(score == null ? 0 : score.doubleValue());
-
-    ActivityEvaluationRecord lastestRecord = baseMapper.queryLastestRecord(
-        activityEvaluation.getActivityId(), userId);
-    if (lastestRecord == null) {
-      activityEvaluationRecord.setTimes(1);
-    } else {
-      activityEvaluationRecord.setTimes(lastestRecord.getTimes() + 1);
+        // 记录曲目评测试分数
+        ActivityEvaluationRecord activityEvaluationRecord = new ActivityEvaluationRecord();
+        activityEvaluationRecord.setActivityId(activityEvaluation.getActivityId());
+        activityEvaluationRecord.setUserId(userId);
+        activityEvaluationRecord.setEvaluationId(evaluationId);
+        activityEvaluationRecord.setResourceId(activityEvaluation.getMusicSheetId());
+        activityEvaluationRecord.setCreateTime(new Date());
+        activityEvaluationRecord.setScore(score == null ? 0 : score.doubleValue());
+
+        ActivityEvaluationRecord lastestRecord = baseMapper.queryLastestRecord(activityEvaluation.getActivityId(), userId);
+        if (lastestRecord == null) {
+            activityEvaluationRecord.setTimes(1);
+        } else {
+            activityEvaluationRecord.setTimes(lastestRecord.getTimes() + 1);
+        }
+        save(activityEvaluationRecord);
+
+        // 活动信息
+        ActivityPlan activity = activityPlanService.getById(activityEvaluation.getActivityId());
+        if (ActivityRankingMethodEnum.TOTAL_SCORE == activity.getRankingMethod()) {
+
+            // 若为总分评测,计算声部分数
+            ThreadPool.getExecutor().submit(() -> {
+
+                List<ActivityEvaluationRecord> records = activityEvaluationRecordService.list(Wrappers.<ActivityEvaluationRecord>lambdaQuery()
+                        .eq(ActivityEvaluationRecord::getActivityId, activityEvaluation.getActivityId())
+                        .eq(ActivityEvaluationRecord::getUserId, userId));
+
+                // 用户当前声部所有评测数据,获取单曲最高进行加和计算为声部最高分
+                Map<Long, Double> highestScoreMap = records.stream()
+                        .filter(x -> Optional.ofNullable(x.getScore()).orElse(0D) > 0)
+                        .collect(Collectors.groupingBy(ActivityEvaluationRecord::getEvaluationId,
+                                Collectors.mapping(ActivityEvaluationRecord::getScore, Collectors.toSet())))
+                        .entrySet().stream()
+                        .collect(Collectors.toMap(Map.Entry::getKey,
+                                x -> x.getValue().stream().mapToDouble(Double::doubleValue).max().orElse(0D), (o, n) -> n));
+
+                // 最高分
+                double sumScore = highestScoreMap.values().stream().mapToDouble(Double::doubleValue).sum();
+
+                // 获取最高分的时间为每个单曲最高分的记录时间
+                Map<Long, Long> highestScoreTimeMap = records.stream()
+                        .filter(x -> highestScoreMap.getOrDefault(x.getEvaluationId(), -1D).doubleValue() == x.getScore())
+                        .collect(Collectors.groupingBy(ActivityEvaluationRecord::getEvaluationId, Collectors.mapping(x -> x.getCreateTime().getTime(), Collectors.toSet())))
+                        .entrySet().stream()
+                        .collect(Collectors.toMap(Map.Entry::getKey,
+                                x -> x.getValue().stream().mapToLong(Long::longValue).max().orElse(0L), (o, n) -> n));
+
+                // 最高分时间
+                long highScoreTime = highestScoreTimeMap.values().stream().mapToLong(Long::longValue).max().orElse(DateTime.now().getMillis());
+
+                // 若分总相同,最高分时间相同,则根据用户活动报名时间进行排序
+                Date registrationTime = records.stream()
+                        .filter(x -> Objects.isNull(x.getScore()))
+                        .min(Comparator.comparing(ActivityEvaluationRecord::getId))
+                        .map(ActivityEvaluationRecord::getCreateTime).orElse(DateTime.now().toDate());
+
+                // 查询用户声部评分记录
+                ActivityEvaluationRecord evaluationRecord = activityEvaluationRecordService.getOne(Wrappers.<ActivityEvaluationRecord>lambdaQuery()
+                        .eq(ActivityEvaluationRecord::getActivityId, activity.getId())
+                        .eq(ActivityEvaluationRecord::getUserId, userId)
+                        .eq(ActivityEvaluationRecord::getRankingMethod, activity.getRankingMethod())
+                );
+
+                if (Objects.isNull(evaluationRecord)) {
+
+                    MusicSheet musicSheet = musicSheetService.getById(activityEvaluation.getMusicSheetId());
+
+                    long subjectId = 0;
+                    if (Objects.nonNull(musicSheet)) {
+                        subjectId = Long.parseLong(musicSheet.getMusicSubject().split(",")[0]);
+                    }
+                    // 添加用户声部总分记录
+                    ActivityEvaluationRecord record = new ActivityEvaluationRecord();
+
+                    record.setActivityId(activityEvaluation.getActivityId());
+                    record.setUserId(userId);
+                    record.setEvaluationId(0L);
+                    // 声部ID
+                    record.setResourceId(subjectId);
+                    record.setRegistrationTime(registrationTime.getTime());
+                    record.setRankingMethod(activity.getRankingMethod());
+                    record.setTimes(0);
+                    // 最高分时间
+                    record.setCreateTime(new DateTime(highScoreTime).toDate());
+                    record.setScore(sumScore);
+
+                    save(record);
+                }
+
+                // 更新最高分记录
+                if (Objects.nonNull(evaluationRecord)
+                        && evaluationRecord.getScore() < sumScore) {
+
+                    ActivityEvaluationRecord record = new ActivityEvaluationRecord();
+
+                    record.setId(evaluationRecord.getId());
+                    record.setScore(sumScore);
+                    record.setCreateTime(new DateTime(highScoreTime).toDate());
+
+                    updateById(record);
+                }
+
+            });
+        }
     }
-    save(activityEvaluationRecord);
-  }
-
 
     @Override
     public void saveActivityRecord(Long activityId, Long userId, Long resourceId, ActivityResourceEnum resourceType) {
         List<ActivityEvaluation> list = activityEvaluationService.lambdaQuery()
-                                                                 .eq(ActivityEvaluation::getActivityId, activityId)
-                                                                 .eq(ActivityEvaluation::getMusicSheetId, resourceId)
-                                                                 .eq(ActivityEvaluation::getResourceType, resourceType)
-                                                                 .list();
+                .eq(ActivityEvaluation::getActivityId, activityId)
+                .eq(ActivityEvaluation::getMusicSheetId, resourceId)
+                .eq(ActivityEvaluation::getResourceType, resourceType)
+                .list();
         ActivityEvaluation activityEvaluation = new ActivityEvaluation();
         if (!CollectionUtils.isEmpty(list)) {
             activityEvaluation = list.get(0);

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

@@ -39,6 +39,7 @@ import com.yonge.cooleshow.biz.dal.service.ActivityRewardService;
 import com.yonge.cooleshow.biz.dal.service.SysMessageService;
 import com.yonge.cooleshow.biz.dal.vo.ActivityMusicVo;
 import com.yonge.cooleshow.biz.dal.vo.ActivityPlanVo;
+import com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo;
 import com.yonge.cooleshow.biz.dal.vo.MusicActivityVo;
 import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
 import com.yonge.cooleshow.biz.dal.vo.activity.ActivityTeacherWrapper;
@@ -521,12 +522,29 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
             // 计算评测活动声部最高分
             if (ActivityRankingMethodEnum.TOTAL_SCORE == activityPlan.getRankingMethod()) {
 
-                Map<Long, List<ActivityMusicVo>> collect = activityMusicVoList.stream()
-                        .collect(Collectors.groupingBy(x -> Long.parseLong(x.getSubjectId().split(",")[0])));
+                Map<String, List<ActivityMusicVo>> collect = activityMusicVoList.stream()
+                        .collect(Collectors.groupingBy(x -> x.getSubjectId().split(",")[0]));
+
+                // 计算声部评测最高分
+                Map<String, ActivityRankingVo> highestScoreMap = Maps.newConcurrentMap();
+                collect.entrySet().parallelStream().forEach(item -> {
+
+                    // 单声部计算用户总分排名用户信息
+                    List<ActivityRankingVo> records = getBaseMapper().selectActivityHighestScoreRankingInfo(activityPlanId, Long.parseLong(item.getKey()),
+                            0D, 1);
+
+                    if (CollectionUtils.isNotEmpty(records)) {
+
+                        highestScoreMap.put(item.getKey(), records.get(0));
+                    }
+                });
+
+                // 最高分用
 
                 List<MusicActivityVo.SubjectInfo> subjectInfos = Lists.newArrayList();
                 ActivityMusicVo musicVo;
-                for (Map.Entry<Long, List<ActivityMusicVo>> entry : collect.entrySet()) {
+                ActivityRankingVo ranking;
+                for (Map.Entry<String, List<ActivityMusicVo>> entry : collect.entrySet()) {
 
                     if (CollectionUtils.isEmpty(entry.getValue())) {
                         continue;
@@ -534,16 +552,28 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
 
                     musicVo = entry.getValue().get(0);
 
-                    subjectInfos.add(MusicActivityVo.SubjectInfo.builder()
-                                    .subjectId(musicVo.getSubjectId().split(",")[0])
-                                    .subjectName(musicVo.getMusicSubject())
-                                    .join(entry.getValue().stream().anyMatch(x -> x.getJoin() == YesOrNoEnum.YES))
-                                    .userId(musicVo.getUserId())
-                                    .username(musicVo.getUsername())
-                                    .userAvatar(musicVo.getUserAvatar())
-                                    .score(0D)
-                                    .musicNums(entry.getValue().size())
-                            .build());
+                    MusicActivityVo.SubjectInfo subjectInfo = MusicActivityVo.SubjectInfo.builder()
+                            .subjectId(musicVo.getSubjectId().split(",")[0])
+                            .subjectName(musicVo.getMusicSubject())
+                            .join(entry.getValue().stream().anyMatch(x -> x.getJoin() == YesOrNoEnum.YES) ? 1 : 0)
+                            .userId(0L)
+                            .username("")
+                            .userAvatar("")
+                            .score(0D)
+                            .musicNums(entry.getValue().size())
+                            .build();
+                    subjectInfos.add(subjectInfo);
+
+                    // 最高分记录
+                    if (highestScoreMap.containsKey(entry.getKey())) {
+
+                        ranking = highestScoreMap.get(entry.getKey());
+
+                        subjectInfo.userId(ranking.getUserId())
+                                .username(ranking.getUsername())
+                                .userAvatar(ranking.getUserAvatar())
+                                .score(ranking.getScore());
+                    }
                 }
 
                 activityVo.setSubjectInfos(subjectInfos);

+ 6 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/ActivityMusicVo.java

@@ -53,8 +53,8 @@ public class ActivityMusicVo {
     @ApiModelProperty("作曲人")
     private String composer;
 
-    @ApiModelProperty("声部图片")
-    private String subjectImage;
+    @ApiModelProperty("曲目图片")
+    private String musicImage;
 
     public Long getUserId() {
         return userId;
@@ -152,11 +152,11 @@ public class ActivityMusicVo {
         this.composer = composer;
     }
 
-    public String getSubjectImage() {
-        return subjectImage;
+    public String getMusicImage() {
+        return musicImage;
     }
 
-    public void setSubjectImage(String subjectImage) {
-        this.subjectImage = subjectImage;
+    public void setMusicImage(String musicImage) {
+        this.musicImage = musicImage;
     }
 }

+ 22 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicActivityVo.java

@@ -93,7 +93,7 @@ public class MusicActivityVo extends ActivityPlan {
         private String subjectName;
 
         @ApiModelProperty("是否已经报名参与 ")
-        private Boolean join;
+        private Integer join;
 
         @ApiModelProperty("最高分")
         private double score;
@@ -109,5 +109,26 @@ public class MusicActivityVo extends ActivityPlan {
 
         @ApiModelProperty("声部曲目数")
         private Integer musicNums;
+
+
+        public SubjectInfo score(double score) {
+            this.score = score;
+            return this;
+        }
+
+        public SubjectInfo userId(Long userId) {
+            this.userId = userId;
+            return this;
+        }
+
+        public SubjectInfo userAvatar(String userAvatar) {
+            this.userAvatar = userAvatar;
+            return this;
+        }
+
+        public SubjectInfo username(String username) {
+            this.username = username;
+            return this;
+        }
     }
 }

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

@@ -67,9 +67,9 @@
         select ms.id_ as musicSheetId
         ,ms.music_sheet_name_ as musicSheetName
         , ms.music_subject_ AS subjectId
+        , ms.title_img_ AS musicImage
         ,s.name_ as musicSubject
         , ms.composer_ AS composer
-        , s.img_ AS subjectImage
         ,ae.id_ as evaluationId
         ,(select if(count(1)>0,1,0) as `join` from activity_evaluation_record aer where aer.evaluation_id_ = ae.id_ and aer.user_id_ = #{userId}) as `join`
         from activity_evaluation ae

+ 15 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/ActivityPlanMapper.xml

@@ -165,4 +165,19 @@
     </select>
     <!--活动参与人数、获奖人数统计-->
 
+    <!--活动总分用户排名-->
+    <select id="selectActivityHighestScoreRankingInfo"
+            resultType="com.yonge.cooleshow.biz.dal.vo.ActivityRankingVo">
+        SELECT
+            t1.score_, t1.user_id_, t2.avatar_ AS userAvatar, t2.username_ AS username
+        FROM
+            activity_evaluation_record t1 LEFT JOIN sys_user t2 ON t1.user_id_ = t2.id_
+        WHERE
+            t1.activity_id_ = #{activityId} AND t1.resource_id_ = #{subjectId} AND t1.ranking_method_ = 'TOTAL_SCORE' AND t1.score_ > #{rankingScore}
+        ORDER BY
+            t1.score_ DESC,
+            t1.registration_time_ ASC
+        LIMIT #{limit}
+    </select>
+    <!--活动总分用户排名-->
 </mapper>