Реализовал сохранение балов за действия

This commit is contained in:
upagge 2020-10-01 19:06:47 +03:00
parent b8f4a5fb2a
commit f8230a5aa8
No known key found for this signature in database
GPG Key ID: 15CD012E46F6BA34
17 changed files with 300 additions and 21 deletions

View File

@ -24,7 +24,7 @@ bitbucketbot:
no-comment-count: 20
comment-count: 100
init:
start-comment-id: 7914
start-comment-id: 8157
use: false
bitbucket:
token: ${BITBUCKET_ADMIN_TOKEN}

View File

@ -7,5 +7,6 @@
<include file="liquibase/v.2.0.0/2020-09-15-fix-task-comments.xml"/>
<include file="liquibase/v.2.0.0/2020-09-20-setting-notify.xml"/>
<include file="liquibase/v.2.0.0/2020-09-20-teamcity.xml"/>
<include file="liquibase/v.2.0.0/2020-10-01-rating.xml"/>
</databaseChangeLog>

View File

@ -0,0 +1,25 @@
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="2020-10-01-create-table-rating-history" author="upagge">
<createTable tableName="rating_history">
<column name="id" type="integer" autoIncrement="true">
<constraints nullable="false" primaryKey="true"/>
</column>
<column name="login" type="varchar(64)">
<constraints nullable="false" foreignKeyName="rating_history_login_person_login"
references="person(login)"/>
</column>
<column name="points" type="integer">
<constraints nullable="false"/>
</column>
<column name="type" type="varchar(64)"/>
<column name="date_add" type="datetime">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>

View File

@ -18,7 +18,7 @@
</appender>
<root level="info">
<appender-ref ref="FILE"/>
<appender-ref ref="STDOUT"/>
</root>
</configuration>

View File

@ -0,0 +1,26 @@
package org.sadtech.bot.vcs.core.domain;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
@Getter
@RequiredArgsConstructor
public enum PointType {
CREATE_PULL_REQUEST(10),
DECLINE_PULL_REQUEST(-CREATE_PULL_REQUEST.getPoints()),
COMMENT_ADD(1),
COMMENT_DELETE(-COMMENT_ADD.getPoints()),
TASK_CREATE(2),
TASK_DELETE(-TASK_CREATE.getPoints()),
TASK_RECIPIENT(-1),
TASK_DELETE_RECIPIENT(1);
private final Integer points;
}

View File

@ -0,0 +1,49 @@
package org.sadtech.bot.vcs.core.domain.entity;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.sadtech.bot.vcs.core.domain.PointType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.time.LocalDateTime;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
@Getter
@Setter
@Entity
@Table(name = "rating_history")
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class RatingHistory {
@Id
@Column(name = "id")
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "login")
private String login;
@Column(name = "points")
private Integer points;
@Enumerated(EnumType.STRING)
@Column(name = "type")
private PointType type;
@Column(name = "date_add")
private LocalDateTime dateAdd;
}

View File

@ -0,0 +1,31 @@
//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;
//
//}

View File

@ -0,0 +1,13 @@
package org.sadtech.bot.vcs.core.repository;
import org.sadtech.basic.context.repository.SimpleManagerRepository;
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
public interface RatingHistoryRepository extends SimpleManagerRepository<RatingHistory, Long> {
}

View File

@ -0,0 +1,24 @@
package org.sadtech.bot.vcs.core.repository.impl;
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;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
@Repository
public class RatingHistoryRepositoryImpl extends AbstractSimpleManagerRepository<RatingHistory, Long> implements RatingHistoryRepository {
private final RatingHistoryJpaRepository jpaRepository;
public RatingHistoryRepositoryImpl(RatingHistoryJpaRepository jpaRepository) {
super(jpaRepository);
this.jpaRepository = jpaRepository;
}
}

View File

@ -0,0 +1,13 @@
package org.sadtech.bot.vcs.core.repository.jpa;
import org.sadtech.bot.vcs.core.domain.entity.RatingHistory;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
public interface RatingHistoryJpaRepository extends JpaRepository<RatingHistory, Long> {
}

View File

@ -26,7 +26,7 @@ import java.util.stream.Collectors;
public class NotificationScheduler {
private static final Set<String> tksLoginNotify = new HashSet<>(Arrays.asList(
"mstruchkov", "emukhin", "ktorgaeva", "imescheryakov", "kkeglev"
"mstruchkov", "emukhin", "imescheryakov", "kkeglev"
));
private final PersonService personService;

View File

@ -0,0 +1,15 @@
package org.sadtech.bot.vcs.core.service;
import lombok.NonNull;
import org.sadtech.bot.vcs.core.domain.PointType;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
public interface RatingService {
void addRating(@NonNull String login, @NonNull PointType type, @NonNull Integer points);
}

View File

@ -1,9 +0,0 @@
package org.sadtech.bot.vcs.core.service;
import lombok.NonNull;
public interface ReportService {
String generateReport(@NonNull String login);
}

View File

@ -2,7 +2,9 @@ package org.sadtech.bot.vcs.core.service.impl;
import lombok.NonNull;
import org.sadtech.basic.core.service.AbstractSimpleManagerService;
import org.sadtech.basic.core.util.Assert;
import org.sadtech.bot.vcs.core.domain.Answer;
import org.sadtech.bot.vcs.core.domain.PointType;
import org.sadtech.bot.vcs.core.domain.entity.Comment;
import org.sadtech.bot.vcs.core.domain.entity.Task;
import org.sadtech.bot.vcs.core.domain.notify.comment.AnswerCommentNotify;
@ -11,6 +13,7 @@ import org.sadtech.bot.vcs.core.exception.NotFoundException;
import org.sadtech.bot.vcs.core.repository.CommentRepository;
import org.sadtech.bot.vcs.core.service.CommentService;
import org.sadtech.bot.vcs.core.service.NotifyService;
import org.sadtech.bot.vcs.core.service.RatingService;
import org.sadtech.bot.vcs.core.service.TaskService;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.convert.ConversionService;
@ -33,6 +36,7 @@ public class CommentServiceImpl extends AbstractSimpleManagerService<Comment, Lo
private final CommentRepository commentRepository;
private final NotifyService notifyService;
private final TaskService taskService;
private final RatingService ratingService;
private final ConversionService conversionService;
@ -40,12 +44,14 @@ public class CommentServiceImpl extends AbstractSimpleManagerService<Comment, Lo
CommentRepository commentRepository,
NotifyService notifyService,
@Lazy TaskService taskService,
RatingService ratingService,
ConversionService conversionService
) {
super(commentRepository);
this.commentRepository = commentRepository;
this.notifyService = notifyService;
this.taskService = taskService;
this.ratingService = ratingService;
this.conversionService = conversionService;
}
@ -61,12 +67,18 @@ public class CommentServiceImpl extends AbstractSimpleManagerService<Comment, Lo
@Override
public Comment create(@NonNull Comment comment) {
Assert.isNotNull(comment.getId(), "При создании объекта должен быть установлен идентификатор");
comment.getAnswers().clear();
final Comment newComment = commentRepository.save(comment);
ratingCreateComment(comment.getAuthor());
notificationPersonal(comment);
return newComment;
}
private void ratingCreateComment(String author) {
ratingService.addRating(author, PointType.COMMENT_ADD, PointType.COMMENT_ADD.getPoints());
}
private void notificationPersonal(@NonNull Comment comment) {
Matcher matcher = PATTERN.matcher(comment.getMessage());
Set<String> recipientsLogins = new HashSet<>();
@ -108,7 +120,7 @@ public class CommentServiceImpl extends AbstractSimpleManagerService<Comment, Lo
taskService.deleteById(task.getId());
final Comment comment = conversionService.convert(task, Comment.class);
final Comment newComment = commentRepository.save(comment);
notificationPersonal(newComment);
ratingService.addRating(newComment.getAuthor(), PointType.COMMENT_ADD, PointType.COMMENT_ADD.getPoints());
return newComment;
}
@ -144,4 +156,12 @@ public class CommentServiceImpl extends AbstractSimpleManagerService<Comment, Lo
}
}
@Override
public void deleteById(@NonNull Long id) {
final Comment comment = commentRepository.findById(id)
.orElseThrow(() -> new NotFoundException("Комментарий не найден"));
ratingService.addRating(comment.getAuthor(), PointType.COMMENT_DELETE, PointType.COMMENT_DELETE.getPoints());
super.deleteById(id);
}
}

View File

@ -9,6 +9,7 @@ import org.sadtech.basic.core.util.Assert;
import org.sadtech.basic.filter.criteria.CriteriaFilter;
import org.sadtech.basic.filter.criteria.CriteriaQuery;
import org.sadtech.bot.vcs.core.domain.IdAndStatusPr;
import org.sadtech.bot.vcs.core.domain.PointType;
import org.sadtech.bot.vcs.core.domain.PullRequestStatus;
import org.sadtech.bot.vcs.core.domain.ReviewerStatus;
import org.sadtech.bot.vcs.core.domain.entity.PullRequest;
@ -26,6 +27,7 @@ import org.sadtech.bot.vcs.core.exception.UpdateException;
import org.sadtech.bot.vcs.core.repository.PullRequestsRepository;
import org.sadtech.bot.vcs.core.service.NotifyService;
import org.sadtech.bot.vcs.core.service.PullRequestsService;
import org.sadtech.bot.vcs.core.service.RatingService;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@ -42,16 +44,19 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
private final NotifyService notifyService;
private final PullRequestsRepository pullRequestsRepository;
private final RatingService ratingService;
private final FilterService<PullRequest, PullRequestFilter> filterService;
protected PullRequestsServiceImpl(
PullRequestsRepository pullRequestsRepository,
NotifyService notifyService,
RatingService ratingService,
@Qualifier("pullRequestFilterService") FilterService<PullRequest, PullRequestFilter> pullRequestsFilterService
) {
super(pullRequestsRepository);
this.notifyService = notifyService;
this.pullRequestsRepository = pullRequestsRepository;
this.ratingService = ratingService;
this.filterService = pullRequestsFilterService;
}
@ -61,6 +66,7 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
final PullRequest newPullRequest = pullRequestsRepository.save(pullRequest);
ratingService.addRating(newPullRequest.getAuthorLogin(), PointType.CREATE_PULL_REQUEST, PointType.CREATE_PULL_REQUEST.getPoints());
notifyService.send(
NewPrNotify.builder()
.author(newPullRequest.getAuthorLogin())
@ -77,14 +83,6 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
return newPullRequest;
}
//
// private Set<Long> getReviewerTelegrams(@NonNull List<Reviewer> reviewers) {
// return personService.getAllTelegramIdByLogin(
// reviewers.stream()
// .map(Reviewer::getPersonLogin)
// .collect(Collectors.toSet())
// );
// }
@Override
public PullRequest update(@NonNull PullRequest pullRequest) {
@ -133,6 +131,7 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
final PullRequestStatus oldStatus = oldPullRequest.getStatus();
final PullRequestStatus newStatus = newPullRequest.getStatus();
if (!oldStatus.equals(newStatus)) {
ratingStatus(oldPullRequest, newPullRequest);
notifyService.send(
StatusPrNotify.builder()
.name(newPullRequest.getTitle())
@ -146,6 +145,21 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
}
}
private void ratingStatus(PullRequest oldPullRequest, PullRequest newPullRequest) {
final String authorLogin = oldPullRequest.getAuthorLogin();
switch (newPullRequest.getStatus()) {
case OPEN:
ratingService.addRating(authorLogin, PointType.CREATE_PULL_REQUEST, PointType.CREATE_PULL_REQUEST.getPoints());
break;
case MERGED:
// TODO: 01.10.2020 Нужно продумать как расчитывать баллы при мерже.
break;
case DECLINED:
ratingService.addRating(authorLogin, PointType.DECLINE_PULL_REQUEST, PointType.DECLINE_PULL_REQUEST.getPoints());
break;
}
}
private void updateReviewers(PullRequest oldPullRequest, PullRequest newPullRequest) {
final Map<String, Reviewer> oldReviewers = oldPullRequest.getReviewers().stream()
.collect(Collectors.toMap(Reviewer::getPersonLogin, reviewer -> reviewer));

View File

@ -0,0 +1,34 @@
package org.sadtech.bot.vcs.core.service.impl;
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.repository.RatingHistoryRepository;
import org.sadtech.bot.vcs.core.service.RatingService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
/**
* // TODO: 01.10.2020 Добавить описание.
*
* @author upagge 01.10.2020
*/
@Service
@RequiredArgsConstructor
public class RatingServiceImpl implements RatingService {
private final RatingHistoryRepository ratingHistoryRepository;
@Override
public void addRating(@NonNull String login, @NonNull PointType type, @NonNull Integer points) {
final RatingHistory ratingHistory = new RatingHistory();
ratingHistory.setLogin(login);
ratingHistory.setPoints(points);
ratingHistory.setType(type);
ratingHistory.setDateAdd(LocalDateTime.now());
ratingHistoryRepository.save(ratingHistory);
}
}

View File

@ -4,6 +4,7 @@ import lombok.NonNull;
import org.sadtech.basic.core.service.AbstractSimpleManagerService;
import org.sadtech.basic.core.util.Assert;
import org.sadtech.bot.vcs.core.domain.Answer;
import org.sadtech.bot.vcs.core.domain.PointType;
import org.sadtech.bot.vcs.core.domain.TaskStatus;
import org.sadtech.bot.vcs.core.domain.entity.Comment;
import org.sadtech.bot.vcs.core.domain.entity.PullRequest;
@ -17,6 +18,7 @@ import org.sadtech.bot.vcs.core.repository.TaskRepository;
import org.sadtech.bot.vcs.core.service.CommentService;
import org.sadtech.bot.vcs.core.service.NotifyService;
import org.sadtech.bot.vcs.core.service.PullRequestsService;
import org.sadtech.bot.vcs.core.service.RatingService;
import org.sadtech.bot.vcs.core.service.TaskService;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Service;
@ -40,6 +42,7 @@ public class TaskServiceImpl extends AbstractSimpleManagerService<Task, Long> im
private final PullRequestsService pullRequestsService;
private final NotifyService notifyService;
private final CommentService commentService;
private final RatingService ratingService;
private final ConversionService conversionService;
@ -48,6 +51,7 @@ public class TaskServiceImpl extends AbstractSimpleManagerService<Task, Long> im
PullRequestsService pullRequestsService,
NotifyService notifyService,
CommentService commentService,
RatingService ratingService,
ConversionService conversionService
) {
super(taskRepository);
@ -55,6 +59,7 @@ public class TaskServiceImpl extends AbstractSimpleManagerService<Task, Long> im
this.pullRequestsService = pullRequestsService;
this.notifyService = notifyService;
this.commentService = commentService;
this.ratingService = ratingService;
this.conversionService = conversionService;
}
@ -65,6 +70,7 @@ public class TaskServiceImpl extends AbstractSimpleManagerService<Task, Long> im
final Task newTask = taskRepository.save(task);
notifyNewTask(task);
notificationPersonal(task);
ratingCreateTask(task.getAuthor(), task.getResponsible());
return newTask;
}
@ -197,4 +203,21 @@ public class TaskServiceImpl extends AbstractSimpleManagerService<Task, Long> im
);
}
@Override
public void deleteById(@NonNull Long id) {
final Task task = taskRepository.findById(id).orElseThrow(() -> new NotFoundException("Задача не найдена"));
ratingDeleteTask(task.getAuthor(), task.getResponsible());
super.deleteById(id);
}
private void ratingCreateTask(String authorLogin, String responsibleLogin) {
ratingService.addRating(authorLogin, PointType.TASK_CREATE, PointType.TASK_CREATE.getPoints());
ratingService.addRating(responsibleLogin, PointType.TASK_RECIPIENT, PointType.TASK_RECIPIENT.getPoints());
}
private void ratingDeleteTask(String authorLogin, String responsibleLogin) {
ratingService.addRating(authorLogin, PointType.TASK_DELETE, PointType.TASK_DELETE.getPoints());
ratingService.addRating(responsibleLogin, PointType.TASK_DELETE_RECIPIENT, PointType.TASK_DELETE_RECIPIENT.getPoints());
}
}