Browse Source

调整总分用户排名

Eric 2 years ago
parent
commit
1066c74dad

+ 4 - 2
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/ActivityPlanDao.java

@@ -5,6 +5,7 @@ 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;
@@ -88,7 +89,8 @@ public interface ActivityPlanDao extends BaseMapper<ActivityPlan> {
 	 * 活动总分用户排名
 	 * @param activityId 活动ID
 	 * @param subjectId 声部ID
-	 * @return List<ActivityEvaluationRecord>
+	 * @return List<ActivityRankingVo>
 	 */
-    List<ActivityEvaluationRecord> selectActivityHighestScoreRankingInfo(@Param("activityId") Long activityId, @Param("subjectId") String subjectId, @Param("rankingScore") Double rankingScore);
+    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;
+    }
 }

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

@@ -1,43 +1,52 @@
 package com.yonge.cooleshow.biz.dal.service.impl;
 
-import java.math.BigDecimal;
-import java.util.Date;
-import java.util.List;
-import java.util.Optional;
-
-import com.google.common.collect.Lists;
-import com.yonge.cooleshow.biz.dal.entity.ActivityPlan;
-import com.yonge.cooleshow.biz.dal.enums.activity.ActivityRankingRuleEnum;
-import com.yonge.cooleshow.biz.dal.service.ActivityPlanService;
-import org.apache.commons.collections.CollectionUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
 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;
 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.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);
 
     @Autowired
     private ActivityEvaluationService activityEvaluationService;
-
+    @Autowired
+    private ActivityEvaluationRecordService activityEvaluationRecordService;
     @Autowired
     private ActivityPlanService activityPlanService;
+    @Autowired
+    private MusicSheetService musicSheetService;
 
 	@Override
     public ActivityEvaluationRecordVo detail(Long id) {
@@ -63,10 +72,13 @@ public class ActivityEvaluationRecordServiceImpl extends ServiceImpl<ActivityEva
         if (activityEvaluation == null) {
             throw new BizException("未找到评测项目");
         }
+
+        // 记录曲目评测试分数
         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());
         
@@ -77,6 +89,96 @@ public class ActivityEvaluationRecordServiceImpl extends ServiceImpl<ActivityEva
         	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);
+                }
+
+            });
+        }
+
     }
 
 

+ 34 - 11
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;
@@ -525,14 +526,24 @@ public class ActivityPlanServiceImpl extends ServiceImpl<ActivityPlanDao, Activi
                         .collect(Collectors.groupingBy(x -> x.getSubjectId().split(",")[0]));
 
                 // 计算声部评测最高分
+                Map<String, ActivityRankingVo> highestScoreMap = Maps.newConcurrentMap();
                 collect.entrySet().parallelStream().forEach(item -> {
 
                     // 单声部计算用户总分排名用户信息
-                    List<ActivityEvaluationRecord> records = getBaseMapper().selectActivityHighestScoreRankingInfo(activityPlanId, item.getKey(), activityPlan.getRankingScore());
+                    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;
+                ActivityRankingVo ranking;
                 for (Map.Entry<String, List<ActivityMusicVo>> entry : collect.entrySet()) {
 
                     if (CollectionUtils.isEmpty(entry.getValue())) {
@@ -541,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) ? 1 : 0)
-                                    .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);

+ 21 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicActivityVo.java

@@ -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;
+        }
     }
 }

+ 11 - 16
cooleshow-user/user-biz/src/main/resources/config/mybatis/ActivityPlanMapper.xml

@@ -167,22 +167,17 @@
 
     <!--活动总分用户排名-->
     <select id="selectActivityHighestScoreRankingInfo"
-            resultType="com.yonge.cooleshow.biz.dal.entity.ActivityEvaluationRecord">
-        SELECT t.user_id_, t.create_time_ FROM (
-           SELECT
-               t0.user_id_,
-               SUM(t0.score_) AS socre_,
-               MIN(t0.create_time_) AS create_time_
-           FROM (
-                    SELECT t1.user_id_, t2.music_sheet_id_, MAX(IFNULL(t1.score_, 0)) AS score_, MIN(t1.create_time_) AS create_time_
-                    FROM activity_evaluation_record t1 JOIN activity_evaluation t2 ON (t1.evaluation_id_ = t2.id_) JOIN `music_sheet` t3 ON (t2.music_sheet_id_ = t3.id_)
-                    WHERE t1.activity_id_ = #{activityId} AND t3.music_subject_ = #{subjectId}
-                    GROUP BY
-                        t1.user_id_,
-                        t2.music_sheet_id_
-                ) t0
-           GROUP BY t0.user_id_
-       ) t WHERE t.socre_ > #{rankingScore} ORDER BY t.socre_ DESC, t.create_time_ ASC LIMIT 1
+            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>