|  | @@ -1,43 +1,63 @@
 | 
	
		
			
				|  |  |  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.dao.ActivityPlanDao;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.dao.StudentDao;
 | 
	
		
			
				|  |  |  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.entity.Student;
 | 
	
		
			
				|  |  | +import com.yonge.cooleshow.biz.dal.entity.Subject;
 | 
	
		
			
				|  |  | +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.service.SubjectService;
 | 
	
		
			
				|  |  |  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;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private ActivityPlanDao activityPlanMapper;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private StudentDao studentMapper;
 | 
	
		
			
				|  |  | +    @Autowired
 | 
	
		
			
				|  |  | +    private SubjectService subjectService;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	@Override
 | 
	
		
			
				|  |  |      public ActivityEvaluationRecordVo detail(Long id) {
 | 
	
	
		
			
				|  | @@ -63,10 +83,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 +100,99 @@ 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)
 | 
	
		
			
				|  |  | +                        .filter(x -> Optional.ofNullable(x.getEvaluationId()).orElse(0L) > 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 -> Optional.ofNullable(x.getScore()).orElse(0D) > 0)
 | 
	
		
			
				|  |  | +                        .filter(x -> Optional.ofNullable(x.getEvaluationId()).orElse(0L) > 0)
 | 
	
		
			
				|  |  | +                        .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);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -105,7 +221,41 @@ public class ActivityEvaluationRecordServiceImpl extends ServiceImpl<ActivityEva
 | 
	
		
			
				|  |  |          if (activityPlan == null) {
 | 
	
		
			
				|  |  |              throw new BizException("活动已结束");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -		return baseMapper.queryRankingList(activityPlanId, activityEvaluationId, limit,activityPlan.getRankingRule());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        List<ActivityRankingVo> activityRankings;
 | 
	
		
			
				|  |  | +        // 活动排名
 | 
	
		
			
				|  |  | +        if (ActivityRankingMethodEnum.TOTAL_SCORE == activityPlan.getRankingMethod()) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 总分排名, 根据声部ID进行查询
 | 
	
		
			
				|  |  | +            activityRankings = activityPlanMapper.selectActivityHighestScoreRankingInfo(activityPlanId, activityEvaluationId,
 | 
	
		
			
				|  |  | +                    1D, limit);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            List<Long> userIds = activityRankings.stream()
 | 
	
		
			
				|  |  | +                    .map(ActivityRankingVo::getUserId).distinct().collect(Collectors.toList());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (CollectionUtils.isNotEmpty(userIds)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                Map<Long, Long> userSubjectMap = studentMapper.selectList(Wrappers.<Student>lambdaQuery().in(Student::getUserId, userIds)).stream()
 | 
	
		
			
				|  |  | +                        .filter(x -> Objects.nonNull(x.getSubjectId()))
 | 
	
		
			
				|  |  | +                        .collect(Collectors.toMap(Student::getUserId, x -> Long.parseLong(Optional.ofNullable(x.getSubjectId()).orElse("0").split(",")[0]), (o, n) -> n));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                Map<Long, String> subjectNameMap = subjectService.findBySubjectByIdList(Lists.newArrayList(userSubjectMap.values())).stream()
 | 
	
		
			
				|  |  | +                        .collect(Collectors.toMap(Subject::getId, Subject::getName, (o, n) -> n));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                for (ActivityRankingVo item : activityRankings) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                    item.setUserSubject(subjectNameMap.getOrDefault(userSubjectMap.get(item.getUserId()), ""));
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 单曲排名
 | 
	
		
			
				|  |  | +            activityRankings = baseMapper.queryRankingList(activityPlanId, activityEvaluationId, limit, activityPlan.getRankingRule());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return activityRankings;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	@Override
 | 
	
	
		
			
				|  | @@ -114,7 +264,37 @@ public class ActivityEvaluationRecordServiceImpl extends ServiceImpl<ActivityEva
 | 
	
		
			
				|  |  |          if (activityPlan == null) {
 | 
	
		
			
				|  |  |              throw new BizException("活动已结束");
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | -        return baseMapper.queryUserRanking(activityPlanId, activityEvaluationId, userId,activityPlan.getRankingRule());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        // 用户排名信息
 | 
	
		
			
				|  |  | +        ActivityRankingVo userRanking;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (ActivityRankingMethodEnum.TOTAL_SCORE == activityPlan.getRankingMethod()) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 总分排名
 | 
	
		
			
				|  |  | +            userRanking = activityPlanMapper.selectActivityHighestScoreUserRanking(activityPlanId, activityEvaluationId,
 | 
	
		
			
				|  |  | +                    1D, userId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 学生声部信息
 | 
	
		
			
				|  |  | +            Student student = studentMapper.selectOne(Wrappers.<Student>lambdaQuery().eq(Student::getUserId, userId));
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            long subjectId = 0;
 | 
	
		
			
				|  |  | +            if (Objects.nonNull(student.getSubjectId())) {
 | 
	
		
			
				|  |  | +                subjectId = Long.parseLong(student.getSubjectId().split(",")[0]);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            Subject subject = subjectService.get(subjectId);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            if (Objects.nonNull(userRanking)) {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                userRanking.setUserSubject(Optional.ofNullable(subject).map(Subject::getName).orElse(""));
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            // 单曲排名
 | 
	
		
			
				|  |  | +            userRanking = baseMapper.queryUserRanking(activityPlanId, activityEvaluationId, userId, activityPlan.getRankingRule());
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return userRanking;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      /**
 |