Расчет таблицы рейтинга
This commit is contained in:
parent
f8230a5aa8
commit
892cb7bed1
@ -0,0 +1,25 @@
|
||||
package org.sadtech.bot.vcs.bitbucket.app.scheduler;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.vcs.core.service.RatingService;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RatingScheduler {
|
||||
|
||||
private final RatingService ratingService;
|
||||
|
||||
@Scheduled(cron = "0 */1 * * * *")
|
||||
private void ratingRecalculation() {
|
||||
ratingService.ratingRecalculation();
|
||||
}
|
||||
|
||||
}
|
@ -25,7 +25,7 @@ bitbucketbot:
|
||||
comment-count: 100
|
||||
init:
|
||||
start-comment-id: 8157
|
||||
use: false
|
||||
use: true
|
||||
bitbucket:
|
||||
token: ${BITBUCKET_ADMIN_TOKEN}
|
||||
url-pull-request-open: http://192.168.236.164:7990/rest/api/1.0/dashboard/pull-requests?limit=150&state=OPEN
|
||||
|
@ -22,4 +22,19 @@
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
<changeSet id="2020-10-01-create-table-rating-list" author="upagge">
|
||||
<createTable tableName="rating_list">
|
||||
<column name="login" type="varchar(64)">
|
||||
<constraints nullable="false" foreignKeyName="rating_list_login_person_login"
|
||||
references="person(login)"/>
|
||||
</column>
|
||||
<column name="number" type="integer">
|
||||
<constraints nullable="false" unique="true"/>
|
||||
</column>
|
||||
<column name="points" type="integer">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</createTable>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
@ -1,31 +1,42 @@
|
||||
//package org.sadtech.bot.vcs.core.domain.entity;
|
||||
//
|
||||
//import lombok.EqualsAndHashCode;
|
||||
//import lombok.Getter;
|
||||
//import lombok.Setter;
|
||||
//
|
||||
//import javax.persistence.Column;
|
||||
//import javax.persistence.Entity;
|
||||
//import javax.persistence.Table;
|
||||
//
|
||||
///**
|
||||
// * // TODO: 01.10.2020 Добавить описание.
|
||||
// *
|
||||
// * @author upagge 01.10.2020
|
||||
// */
|
||||
//
|
||||
//@Getter
|
||||
//@Setter
|
||||
//@Entity
|
||||
//@Table(name = "rating_list")
|
||||
//@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
//public class RatingList {
|
||||
//
|
||||
// @Column(name = "login")
|
||||
// @EqualsAndHashCode.Include
|
||||
// private String login;
|
||||
//
|
||||
// @Column(name = "points")
|
||||
// private Integer points;
|
||||
//
|
||||
//}
|
||||
package org.sadtech.bot.vcs.core.domain.entity;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "rating_list")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class RatingList implements Comparable<RatingList> {
|
||||
|
||||
@Id
|
||||
@Column(name = "login")
|
||||
@EqualsAndHashCode.Include
|
||||
private String login;
|
||||
|
||||
@Column(name = "points")
|
||||
private Integer points;
|
||||
|
||||
@Column(name = "number")
|
||||
private Integer number;
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull RatingList ratingList) {
|
||||
return Integer.compare(ratingList.getPoints(), points);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
package org.sadtech.bot.vcs.core.repository;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.basic.context.repository.SimpleManagerRepository;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
@ -10,4 +14,6 @@ import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
|
||||
*/
|
||||
public interface RatingHistoryRepository extends SimpleManagerRepository<RatingHistory, Long> {
|
||||
|
||||
List<RatingHistory> findAllByDateAddBetween(@NonNull LocalDateTime from, @NonNull LocalDateTime to);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package org.sadtech.bot.vcs.core.repository;
|
||||
|
||||
import org.sadtech.basic.context.repository.SimpleManagerRepository;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
public interface RatingListRepository extends SimpleManagerRepository<RatingList, String> {
|
||||
|
||||
Optional<RatingList> getByLogin(String login);
|
||||
|
||||
List<RatingList> findFirstThree();
|
||||
|
||||
List<RatingList> findLastThree();
|
||||
|
||||
long count();
|
||||
|
||||
}
|
@ -1,11 +1,15 @@
|
||||
package org.sadtech.bot.vcs.core.repository.impl;
|
||||
|
||||
import lombok.NonNull;
|
||||
import org.sadtech.basic.database.repository.manager.AbstractSimpleManagerRepository;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
|
||||
import org.sadtech.bot.vcs.core.repository.RatingHistoryRepository;
|
||||
import org.sadtech.bot.vcs.core.repository.jpa.RatingHistoryJpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
@ -21,4 +25,9 @@ public class RatingHistoryRepositoryImpl extends AbstractSimpleManagerRepository
|
||||
this.jpaRepository = jpaRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RatingHistory> findAllByDateAddBetween(@NonNull LocalDateTime from, @NonNull LocalDateTime to) {
|
||||
return jpaRepository.findAllByDateAddBetween(from, to);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
package org.sadtech.bot.vcs.core.repository.impl;
|
||||
|
||||
import org.sadtech.basic.database.repository.manager.AbstractSimpleManagerRepository;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingList;
|
||||
import org.sadtech.bot.vcs.core.repository.RatingListRepository;
|
||||
import org.sadtech.bot.vcs.core.repository.jpa.RatingListJpaRepository;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
@Repository
|
||||
public class RatingListRepositoryImpl extends AbstractSimpleManagerRepository<RatingList, String> implements RatingListRepository {
|
||||
|
||||
private final RatingListJpaRepository jpaRepository;
|
||||
|
||||
public RatingListRepositoryImpl(RatingListJpaRepository jpaRepository) {
|
||||
super(jpaRepository);
|
||||
this.jpaRepository = jpaRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RatingList> getByLogin(String login) {
|
||||
return jpaRepository.findById(login);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RatingList> findFirstThree() {
|
||||
return jpaRepository.findAll(
|
||||
PageRequest.of(0, 3, Sort.by(Sort.Direction.ASC, "number"))
|
||||
).getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RatingList> findLastThree() {
|
||||
return jpaRepository.findAll(
|
||||
PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "number"))
|
||||
).getContent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count() {
|
||||
return jpaRepository.count();
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,9 @@ package org.sadtech.bot.vcs.core.repository.jpa;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
@ -10,4 +13,6 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
*/
|
||||
public interface RatingHistoryJpaRepository extends JpaRepository<RatingHistory, Long> {
|
||||
|
||||
List<RatingHistory> findAllByDateAddBetween(LocalDateTime from, LocalDateTime to);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package org.sadtech.bot.vcs.core.repository.jpa;
|
||||
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingList;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
public interface RatingListJpaRepository extends JpaRepository<RatingList, String> {
|
||||
|
||||
}
|
@ -12,4 +12,8 @@ public interface RatingService {
|
||||
|
||||
void addRating(@NonNull String login, @NonNull PointType type, @NonNull Integer points);
|
||||
|
||||
void ratingRecalculation();
|
||||
|
||||
String getRatingTop(@NonNull String login);
|
||||
|
||||
}
|
||||
|
@ -4,11 +4,19 @@ import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.vcs.core.domain.PointType;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.RatingList;
|
||||
import org.sadtech.bot.vcs.core.exception.NotFoundException;
|
||||
import org.sadtech.bot.vcs.core.repository.RatingHistoryRepository;
|
||||
import org.sadtech.bot.vcs.core.repository.RatingListRepository;
|
||||
import org.sadtech.bot.vcs.core.service.RatingService;
|
||||
import org.sadtech.bot.vcs.core.utils.Smile;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
@ -20,6 +28,7 @@ import java.time.LocalDateTime;
|
||||
public class RatingServiceImpl implements RatingService {
|
||||
|
||||
private final RatingHistoryRepository ratingHistoryRepository;
|
||||
private final RatingListRepository ratingListRepository;
|
||||
|
||||
@Override
|
||||
public void addRating(@NonNull String login, @NonNull PointType type, @NonNull Integer points) {
|
||||
@ -31,4 +40,67 @@ public class RatingServiceImpl implements RatingService {
|
||||
ratingHistoryRepository.save(ratingHistory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ratingRecalculation() {
|
||||
AtomicInteger i = new AtomicInteger();
|
||||
final List<RatingList> newRatingList = ratingHistoryRepository.findAllByDateAddBetween(LocalDateTime.now().minusDays(30L), LocalDateTime.now()).stream()
|
||||
.collect(Collectors.groupingBy(RatingHistory::getLogin, Collectors.summingInt(RatingHistory::getPoints)))
|
||||
.entrySet().stream()
|
||||
.map(this::createRatingList)
|
||||
.sorted()
|
||||
.peek(ratingList -> ratingList.setNumber(i.getAndIncrement()))
|
||||
.collect(Collectors.toList());
|
||||
ratingListRepository.saveAll(newRatingList);
|
||||
}
|
||||
|
||||
private RatingList createRatingList(Map.Entry<String, Integer> entry) {
|
||||
final RatingList ratingList = new RatingList();
|
||||
ratingList.setLogin(entry.getKey());
|
||||
ratingList.setPoints(entry.getValue());
|
||||
return ratingList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRatingTop(@NonNull String login) {
|
||||
final RatingList personRating = ratingListRepository.getByLogin(login)
|
||||
.orElseThrow(() -> new NotFoundException("Пользователь не найден"));
|
||||
final Integer numberRatingList = personRating.getNumber();
|
||||
final long countPerson = ratingListRepository.count();
|
||||
final String threeMessage = ratingListRepository.findFirstThree().stream()
|
||||
.map(this::createString)
|
||||
.collect(Collectors.joining("\n"));
|
||||
final String lastMessage = ratingListRepository.findLastThree().stream()
|
||||
.map(this::createString)
|
||||
.limit(countPerson - 3)
|
||||
.collect(Collectors.joining("\n"));
|
||||
String message = threeMessage;
|
||||
|
||||
if (numberRatingList <= 2) {
|
||||
if (countPerson > 3) {
|
||||
message += "\n... ... ...\n";
|
||||
}
|
||||
} else if (numberRatingList > 3 && numberRatingList <= (countPerson - 3)) {
|
||||
message += "\n... ... ...\n" + personRating.getNumber() + ": " + personRating.getLogin() + "\n... ... ...\n";
|
||||
} else {
|
||||
message += "\n... ... ...\n";
|
||||
}
|
||||
message += lastMessage;
|
||||
return message;
|
||||
}
|
||||
|
||||
private String createString(RatingList ratingList) {
|
||||
String message = "";
|
||||
final Integer number = ratingList.getNumber();
|
||||
if (number == 0) {
|
||||
message += Smile.TOP_ONE + " " + ratingList.getLogin() + " " + Smile.TOP_ONE;
|
||||
} else if (number == 1) {
|
||||
message += Smile.TOP_TWO + " " + ratingList.getLogin() + " " + Smile.TOP_TWO;
|
||||
} else if (number == 2) {
|
||||
message += Smile.TOP_THREE + " " + ratingList.getLogin() + " " + Smile.TOP_THREE;
|
||||
} else {
|
||||
message += Smile.KAKASHKA + " " + ratingList.getLogin();
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ public enum Smile {
|
||||
DAY_4("\uD83C\uDF11"),
|
||||
DAY_5("\uD83C\uDF1A"),
|
||||
TASK("\uD83D\uDCBC"),
|
||||
TOP_ONE("\uD83C\uDF1F\uD83C\uDF1F\uD83C\uDF1F"),
|
||||
TOP_TWO("\uD83D\uDE0E"),
|
||||
TOP_THREE("\uD83E\uDD49"),
|
||||
KAKASHKA("\uD83D\uDCA9"),
|
||||
MEGA_FUN("\uD83D\uDE02"),
|
||||
DANGEROUS("⚠️"),
|
||||
BELL("\uD83D\uDECE"),
|
||||
|
@ -0,0 +1,33 @@
|
||||
package org.sadtech.bot.vcs.telegram.service.unit;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.Person;
|
||||
import org.sadtech.bot.vcs.core.exception.NotFoundException;
|
||||
import org.sadtech.bot.vcs.core.service.PersonService;
|
||||
import org.sadtech.bot.vcs.core.service.RatingService;
|
||||
import org.sadtech.social.bot.service.usercode.ProcessingData;
|
||||
import org.sadtech.social.core.domain.BoxAnswer;
|
||||
import org.sadtech.social.core.domain.content.Message;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* // TODO: 01.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 01.10.2020
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class RatingTopProcessing implements ProcessingData<Message> {
|
||||
|
||||
private final RatingService ratingService;
|
||||
private final PersonService personService;
|
||||
|
||||
@Override
|
||||
public BoxAnswer processing(Message content) {
|
||||
final Person person = personService.getByTelegramId(content.getPersonId())
|
||||
.orElseThrow(() -> new NotFoundException("Пользователь не найден"));
|
||||
return BoxAnswer.builder()
|
||||
.message(ratingService.getRatingTop(person.getLogin()))
|
||||
.build();
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package org.sadtech.bot.vcs.telegram.unit;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.sadtech.bot.vcs.core.service.PersonService;
|
||||
import org.sadtech.bot.vcs.telegram.service.unit.PullRequestProcessing;
|
||||
import org.sadtech.bot.vcs.telegram.service.unit.RatingTopProcessing;
|
||||
import org.sadtech.bot.vcs.telegram.service.unit.TaskProcessing;
|
||||
import org.sadtech.bot.vcs.telegram.utils.GeneratorKeyBoards;
|
||||
import org.sadtech.social.bot.domain.unit.AnswerCheck;
|
||||
@ -44,7 +45,8 @@ public class UnitConfig {
|
||||
public AnswerText menu(
|
||||
AnswerProcessing<Message> getTasks,
|
||||
AnswerProcessing<Message> getPr,
|
||||
AnswerText settings
|
||||
AnswerText settings,
|
||||
AnswerProcessing<Message> getTopRating
|
||||
) {
|
||||
return AnswerText.builder()
|
||||
.boxAnswer(
|
||||
@ -56,6 +58,7 @@ public class UnitConfig {
|
||||
.nextUnit(getTasks)
|
||||
.nextUnit(getPr)
|
||||
.nextUnit(settings)
|
||||
.nextUnit(getTopRating)
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -97,6 +100,16 @@ public class UnitConfig {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
AnswerProcessing<Message> getTopRating(
|
||||
RatingTopProcessing ratingTopProcessing
|
||||
) {
|
||||
return AnswerProcessing.builder()
|
||||
.processingData(ratingTopProcessing)
|
||||
.keyWord("таблица")
|
||||
.keyWord("рейтинга")
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public AnswerProcessing<Mail> noRegister() {
|
||||
|
@ -17,6 +17,7 @@ public class GeneratorKeyBoards {
|
||||
public static KeyBoard menu() {
|
||||
final KeyBoardButtonText tasks = KeyBoardButtonText.builder().label("Мои задачи").build();
|
||||
final KeyBoardButtonText pr = KeyBoardButtonText.builder().label("Проверить ПР").build();
|
||||
final KeyBoardButtonText top = KeyBoardButtonText.builder().label("\uD83C\uDF1F Таблица рейтинга \uD83C\uDF1F").build();
|
||||
final KeyBoardButtonText settings = KeyBoardButtonText.builder().label("Настройки").build();
|
||||
|
||||
final KeyBoardLine oneLine = KeyBoardLine.builder()
|
||||
@ -25,12 +26,17 @@ public class GeneratorKeyBoards {
|
||||
.build();
|
||||
|
||||
final KeyBoardLine twoLine = KeyBoardLine.builder()
|
||||
.buttonKeyBoard(top)
|
||||
.build();
|
||||
|
||||
final KeyBoardLine threeLine = KeyBoardLine.builder()
|
||||
.buttonKeyBoard(settings)
|
||||
.build();
|
||||
|
||||
return KeyBoard.builder()
|
||||
.lineKeyBoard(oneLine)
|
||||
.lineKeyBoard(twoLine)
|
||||
.lineKeyBoard(threeLine)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user