#112 ping activity
This commit is contained in:
parent
a35bcfce1b
commit
e680aa30c4
@ -5,8 +5,10 @@ import org.hibernate.annotations.FetchMode;
|
|||||||
import org.hibernate.validator.constraints.NotBlank;
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.paper.model.Paper;
|
import ru.ulstu.paper.model.Paper;
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Column;
|
import javax.persistence.Column;
|
||||||
@ -25,10 +27,12 @@ import java.util.Comparator;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "conference")
|
@Table(name = "conference")
|
||||||
public class Conference extends BaseEntity {
|
public class Conference extends BaseEntity implements UserActivity {
|
||||||
|
|
||||||
@NotBlank
|
@NotBlank
|
||||||
private String title;
|
private String title;
|
||||||
@ -147,4 +151,9 @@ public class Conference extends BaseEntity {
|
|||||||
.filter(d -> d.getDate().after(new Date()))
|
.filter(d -> d.getDate().after(new Date()))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<User> getActivityUsers() {
|
||||||
|
return getUsers().stream().map(ConferenceUser::getUser).collect(Collectors.toSet());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import ru.ulstu.user.model.User;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public interface UserContainer {
|
public interface UserActivity {
|
||||||
Set<User> getUsers();
|
String getTitle();
|
||||||
|
Set<User> getActivityUsers();
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import org.hibernate.annotations.Fetch;
|
|||||||
import org.hibernate.annotations.FetchMode;
|
import org.hibernate.annotations.FetchMode;
|
||||||
import org.hibernate.validator.constraints.NotBlank;
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
import ru.ulstu.core.model.UserContainer;
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.file.model.FileData;
|
import ru.ulstu.file.model.FileData;
|
||||||
import ru.ulstu.paper.model.Paper;
|
import ru.ulstu.paper.model.Paper;
|
||||||
@ -35,7 +35,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "grants")
|
@Table(name = "grants")
|
||||||
public class Grant extends BaseEntity implements UserContainer {
|
public class Grant extends BaseEntity implements UserActivity {
|
||||||
public enum GrantStatus {
|
public enum GrantStatus {
|
||||||
APPLICATION("Заявка"),
|
APPLICATION("Заявка"),
|
||||||
ON_COMPETITION("Отправлен на конкурс"),
|
ON_COMPETITION("Отправлен на конкурс"),
|
||||||
@ -155,7 +155,7 @@ public class Grant extends BaseEntity implements UserContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<User> getUsers() {
|
public Set<User> getActivityUsers() {
|
||||||
return getAuthors();
|
return getAuthors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import org.hibernate.annotations.FetchMode;
|
|||||||
import org.hibernate.validator.constraints.NotBlank;
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
import ru.ulstu.conference.model.Conference;
|
import ru.ulstu.conference.model.Conference;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
import ru.ulstu.core.model.UserContainer;
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.file.model.FileData;
|
import ru.ulstu.file.model.FileData;
|
||||||
import ru.ulstu.grant.model.Grant;
|
import ru.ulstu.grant.model.Grant;
|
||||||
@ -34,7 +34,7 @@ import java.util.Optional;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Paper extends BaseEntity implements UserContainer {
|
public class Paper extends BaseEntity implements UserActivity {
|
||||||
public enum PaperStatus {
|
public enum PaperStatus {
|
||||||
ATTENTION("Обратить внимание"),
|
ATTENTION("Обратить внимание"),
|
||||||
ON_PREPARATION("На подготовке"),
|
ON_PREPARATION("На подготовке"),
|
||||||
@ -249,7 +249,7 @@ public class Paper extends BaseEntity implements UserContainer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<User> getUsers() {
|
public Set<User> getActivityUsers() {
|
||||||
return getAuthors();
|
return getAuthors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package ru.ulstu.paper.service;
|
package ru.ulstu.paper.service;
|
||||||
|
|
||||||
import com.sun.deploy.pings.Pings;
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
|||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import ru.ulstu.conference.model.Conference;
|
import ru.ulstu.conference.model.Conference;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.grant.model.Grant;
|
import ru.ulstu.grant.model.Grant;
|
||||||
import ru.ulstu.paper.model.Paper;
|
import ru.ulstu.paper.model.Paper;
|
||||||
import ru.ulstu.project.model.Project;
|
import ru.ulstu.project.model.Project;
|
||||||
@ -121,4 +122,16 @@ public class Ping extends BaseEntity {
|
|||||||
this.paper = (Paper) object;
|
this.paper = (Paper) object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UserActivity getActivity() {
|
||||||
|
if (conference != null) {
|
||||||
|
return conference;
|
||||||
|
} else if (project != null) {
|
||||||
|
return project;
|
||||||
|
} else if (paper != null) {
|
||||||
|
return paper;
|
||||||
|
} else {
|
||||||
|
return grant;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
35
src/main/java/ru/ulstu/ping/model/PingInfo.java
Normal file
35
src/main/java/ru/ulstu/ping/model/PingInfo.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package ru.ulstu.ping.model;
|
||||||
|
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class PingInfo {
|
||||||
|
private User user;
|
||||||
|
private List<Ping> pings = new ArrayList<>();
|
||||||
|
|
||||||
|
public PingInfo(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Ping> getPings() {
|
||||||
|
return pings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPings(List<Ping> pings) {
|
||||||
|
this.pings = pings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPing(Ping ping) {
|
||||||
|
this.pings.add(ping);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import org.springframework.data.repository.query.Param;
|
|||||||
import ru.ulstu.conference.model.Conference;
|
import ru.ulstu.conference.model.Conference;
|
||||||
import ru.ulstu.ping.model.Ping;
|
import ru.ulstu.ping.model.Ping;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface PingRepository extends JpaRepository<Ping, Integer> {
|
public interface PingRepository extends JpaRepository<Ping, Integer> {
|
||||||
@ -13,9 +14,11 @@ public interface PingRepository extends JpaRepository<Ping, Integer> {
|
|||||||
@Query("SELECT count(*) FROM Ping p WHERE (DAY(p.date) = :day) AND (MONTH(p.date) = :month) AND (YEAR(p.date) = :year) AND (p.conference = :conference)")
|
@Query("SELECT count(*) FROM Ping p WHERE (DAY(p.date) = :day) AND (MONTH(p.date) = :month) AND (YEAR(p.date) = :year) AND (p.conference = :conference)")
|
||||||
long countByConferenceAndDate(@Param("conference") Conference conference, @Param("day") Integer day, @Param("month") Integer month, @Param("year") Integer year);
|
long countByConferenceAndDate(@Param("conference") Conference conference, @Param("day") Integer day, @Param("month") Integer month, @Param("year") Integer year);
|
||||||
|
|
||||||
@Query("SELECT p FROM Ping p WHERE (:user IS NULL OR p.user.id = :user) " +
|
@Query("SELECT p FROM Ping p WHERE (:activity != 'conferences' OR p.conference IS NOT NULL) " +
|
||||||
"AND (:activity != 'conferences' OR p.conference IS NOT NULL) AND (:activity != 'papers' OR p.paper IS NOT NULL) " +
|
"AND (:activity != 'papers' OR p.paper IS NOT NULL) AND (:activity != 'projects' OR p.project IS NOT NULL) " +
|
||||||
"AND (:activity != 'projects' OR p.project IS NOT NULL) AND (:activity != 'grants' OR p.grant IS NOT NULL)")
|
"AND (:activity != 'grants' OR p.grant IS NOT NULL)")
|
||||||
List<Ping> getPings(@Param("user") Integer user,
|
List<Ping> getPings(@Param("activity") String activity);
|
||||||
@Param("activity") String activity);
|
|
||||||
|
@Query("SELECT p FROM Ping p WHERE (:dateFrom < date)")
|
||||||
|
List<Ping> findByDate(@Param("dateFrom") Date dateFrom);
|
||||||
}
|
}
|
||||||
|
59
src/main/java/ru/ulstu/ping/service/PingScheduler.java
Normal file
59
src/main/java/ru/ulstu/ping/service/PingScheduler.java
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package ru.ulstu.ping.service;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.core.model.UserActivity;
|
||||||
|
import ru.ulstu.ping.model.Ping;
|
||||||
|
import ru.ulstu.ping.model.PingInfo;
|
||||||
|
import ru.ulstu.ping.repository.PingRepository;
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
import ru.ulstu.user.service.MailService;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class PingScheduler {
|
||||||
|
private final Logger log = LoggerFactory.getLogger(PingScheduler.class);
|
||||||
|
private final PingRepository pingRepository;
|
||||||
|
private final MailService mailService;
|
||||||
|
private final static String PING_MAIL_SUBJECT = "Ping статистика";
|
||||||
|
|
||||||
|
public PingScheduler(PingRepository pingRepository, MailService mailService) {
|
||||||
|
this.pingRepository = pingRepository;
|
||||||
|
this.mailService = mailService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 * * 1 ?")
|
||||||
|
public void sendPingsInfo() {
|
||||||
|
log.debug("Scheduler.sendPingsInfo started");
|
||||||
|
|
||||||
|
List<PingInfo> pingInfos = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Ping ping : pingRepository.findByDate(java.sql.Date.valueOf(LocalDate.now().minusWeeks(1)))) {
|
||||||
|
UserActivity pingActivity = ping.getActivity();
|
||||||
|
Set<User> users = pingActivity.getActivityUsers();
|
||||||
|
|
||||||
|
for (User user : users) {
|
||||||
|
PingInfo userPing = pingInfos.stream().filter(u -> u.getUser() == user).findFirst().orElse(null);
|
||||||
|
if (userPing == null) {
|
||||||
|
userPing = new PingInfo(user);
|
||||||
|
pingInfos.add(userPing);
|
||||||
|
}
|
||||||
|
userPing.addPing(ping);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PingInfo pingInfo : pingInfos) {
|
||||||
|
mailService.sendEmailFromTemplate(ImmutableMap.of("pings", pingInfo.getPings()),
|
||||||
|
pingInfo.getUser(), "pingsInfoWeekEmail", PING_MAIL_SUBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -16,15 +16,19 @@ import java.util.List;
|
|||||||
public class PingService {
|
public class PingService {
|
||||||
private final PingRepository pingRepository;
|
private final PingRepository pingRepository;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
private final PingScheduler pingScheduler;
|
||||||
|
|
||||||
public PingService(PingRepository pingRepository,
|
public PingService(PingRepository pingRepository,
|
||||||
UserService userService) {
|
UserService userService,
|
||||||
|
PingScheduler pingScheduler) {
|
||||||
this.pingRepository = pingRepository;
|
this.pingRepository = pingRepository;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
|
this.pingScheduler = pingScheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public <T> Ping addPing(T activity) throws IOException {
|
public <T> Ping addPing(T activity) throws IOException {
|
||||||
|
pingScheduler.sendPingsInfo();
|
||||||
Ping newPing = new Ping(new Date(), userService.getCurrentUser());
|
Ping newPing = new Ping(new Date(), userService.getCurrentUser());
|
||||||
newPing.setActivity(activity);
|
newPing.setActivity(activity);
|
||||||
return pingRepository.save(newPing);
|
return pingRepository.save(newPing);
|
||||||
@ -35,7 +39,7 @@ public class PingService {
|
|||||||
calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR)));
|
calendar.get(Calendar.MONTH) + 1, calendar.get(Calendar.YEAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Ping> getPings(Integer userId, String activity) {
|
public List<Ping> getPings(String activity) {
|
||||||
return pingRepository.getPings(userId, activity);
|
return pingRepository.getPings(activity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package ru.ulstu.project.model;
|
|||||||
|
|
||||||
import org.hibernate.validator.constraints.NotBlank;
|
import org.hibernate.validator.constraints.NotBlank;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.file.model.FileData;
|
import ru.ulstu.file.model.FileData;
|
||||||
import ru.ulstu.grant.model.Grant;
|
import ru.ulstu.grant.model.Grant;
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
@ -15,10 +17,17 @@ import javax.persistence.ManyToOne;
|
|||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class Project extends BaseEntity {
|
public class Project extends BaseEntity implements UserActivity {
|
||||||
|
@Override
|
||||||
|
public Set<User> getActivityUsers() {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
public enum ProjectStatus {
|
public enum ProjectStatus {
|
||||||
APPLICATION("Заявка"),
|
APPLICATION("Заявка"),
|
||||||
ON_COMPETITION("Отправлен на конкурс"),
|
ON_COMPETITION("Отправлен на конкурс"),
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
package ru.ulstu.strategy.api;
|
package ru.ulstu.strategy.api;
|
||||||
|
|
||||||
import ru.ulstu.core.model.UserContainer;
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public abstract class EntityCreateStrategy<T extends UserContainer> {
|
public abstract class EntityCreateStrategy<T extends UserActivity> {
|
||||||
protected abstract List<T> getActiveEntities();
|
protected abstract List<T> getActiveEntities();
|
||||||
|
|
||||||
protected abstract void createEntity(User user);
|
protected abstract void createEntity(User user);
|
||||||
|
|
||||||
protected void createDefaultEntityIfNeed(List<User> allUsers, List<? extends UserContainer> entities) {
|
protected void createDefaultEntityIfNeed(List<User> allUsers, List<? extends UserActivity> entities) {
|
||||||
allUsers.forEach(user -> {
|
allUsers.forEach(user -> {
|
||||||
if (entities
|
if (entities
|
||||||
.stream()
|
.stream()
|
||||||
.filter(entity -> entity.getUsers().contains(user))
|
.filter(entity -> entity.getActivityUsers().contains(user))
|
||||||
.collect(Collectors.toSet()).isEmpty()) {
|
.collect(Collectors.toSet()).isEmpty()) {
|
||||||
createEntity(user);
|
createEntity(user);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import ru.ulstu.odin.controller.OdinController;
|
|||||||
import ru.ulstu.odin.model.OdinMetadata;
|
import ru.ulstu.odin.model.OdinMetadata;
|
||||||
import ru.ulstu.odin.model.OdinVoid;
|
import ru.ulstu.odin.model.OdinVoid;
|
||||||
import ru.ulstu.odin.service.OdinService;
|
import ru.ulstu.odin.service.OdinService;
|
||||||
import ru.ulstu.user.model.DiagramElement;
|
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
import ru.ulstu.user.model.UserDto;
|
import ru.ulstu.user.model.UserDto;
|
||||||
import ru.ulstu.user.model.UserListDto;
|
import ru.ulstu.user.model.UserListDto;
|
||||||
@ -35,7 +34,6 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static ru.ulstu.user.controller.UserController.URL;
|
import static ru.ulstu.user.controller.UserController.URL;
|
||||||
@ -175,7 +173,7 @@ public class UserController extends OdinController<UserListDto, UserDto> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/activities/pings")
|
@GetMapping("/activities/pings")
|
||||||
public Response<List<DiagramElement>> getActivitesStats(@RequestParam(value = "userId", required = false) Integer userId,
|
public Response<Map<String, Integer>> getActivitesStats(@RequestParam(value = "userId", required = false) Integer userId,
|
||||||
@RequestParam(value = "activity", required = false) String activity) {
|
@RequestParam(value = "activity", required = false) String activity) {
|
||||||
return new Response<>(userService.getActivitiesPings(userId, activity));
|
return new Response<>(userService.getActivitiesPings(userId, activity));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package ru.ulstu.user.controller;
|
package ru.ulstu.user.controller;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
@ -18,8 +19,8 @@ import ru.ulstu.user.service.UserSessionService;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping(value = "/users")
|
@RequestMapping(value = "/users")
|
||||||
@ -58,12 +59,14 @@ public class UserMvcController extends OdinController<UserListDto, UserDto> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ModelAttribute("allActivities")
|
@ModelAttribute("allActivities")
|
||||||
public List<String> getAllActivites() {
|
public Map<String, String> getAllActivites() {
|
||||||
return new ArrayList<String>() {{
|
return ImmutableMap.of("papers", "Статьи",
|
||||||
add("papers");
|
"grants", "Гранты",
|
||||||
add("projects");
|
"projects", "Проекты",
|
||||||
add("grants");
|
"conferences", "Конференции");
|
||||||
add("conferences");
|
}
|
||||||
}};
|
|
||||||
|
@GetMapping("/pings")
|
||||||
|
public void getPings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,86 +0,0 @@
|
|||||||
package ru.ulstu.user.model;
|
|
||||||
|
|
||||||
import ru.ulstu.ping.model.Ping;
|
|
||||||
|
|
||||||
public class DiagramElement {
|
|
||||||
private User user;
|
|
||||||
private int conferences = 0;
|
|
||||||
private int projects = 0;
|
|
||||||
private int grants = 0;
|
|
||||||
private int papers = 0;
|
|
||||||
|
|
||||||
public DiagramElement() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public DiagramElement(User user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public User getUser() {
|
|
||||||
return user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUser(User user) {
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getConferences() {
|
|
||||||
return conferences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConferences(int conferences) {
|
|
||||||
this.conferences = conferences;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getProjects() {
|
|
||||||
return projects;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setProjects(int projects) {
|
|
||||||
this.projects = projects;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getGrants() {
|
|
||||||
return grants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGrants(int grants) {
|
|
||||||
this.grants = grants;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPapers() {
|
|
||||||
return papers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPapers(int papers) {
|
|
||||||
this.papers = papers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementPapers(int value) {
|
|
||||||
this.papers ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementProjects(int value) {
|
|
||||||
this.projects ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementConferences(int value) {
|
|
||||||
this.conferences ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementGrants(int value) {
|
|
||||||
this.grants ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void incrementActivity(Ping ping) {
|
|
||||||
if (ping.getConference() != null) {
|
|
||||||
this.conferences ++;
|
|
||||||
} else if(ping.getPaper() != null) {
|
|
||||||
this.papers ++;
|
|
||||||
} else if(ping.getProject() != null) {
|
|
||||||
this.projects ++;
|
|
||||||
} else if(ping.getGrant() != null) {
|
|
||||||
this.grants ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -18,6 +18,7 @@ import ru.ulstu.configuration.ApplicationProperties;
|
|||||||
import ru.ulstu.core.error.EntityIdIsNullException;
|
import ru.ulstu.core.error.EntityIdIsNullException;
|
||||||
import ru.ulstu.core.jpa.OffsetablePageRequest;
|
import ru.ulstu.core.jpa.OffsetablePageRequest;
|
||||||
import ru.ulstu.core.model.BaseEntity;
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
import ru.ulstu.core.model.UserActivity;
|
||||||
import ru.ulstu.core.model.response.PageableItems;
|
import ru.ulstu.core.model.response.PageableItems;
|
||||||
import ru.ulstu.ping.model.Ping;
|
import ru.ulstu.ping.model.Ping;
|
||||||
import ru.ulstu.ping.service.PingService;
|
import ru.ulstu.ping.service.PingService;
|
||||||
@ -31,7 +32,6 @@ import ru.ulstu.user.error.UserNotFoundException;
|
|||||||
import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException;
|
import ru.ulstu.user.error.UserPasswordsNotValidOrNotMatchException;
|
||||||
import ru.ulstu.user.error.UserResetKeyError;
|
import ru.ulstu.user.error.UserResetKeyError;
|
||||||
import ru.ulstu.user.error.UserSendingMailException;
|
import ru.ulstu.user.error.UserSendingMailException;
|
||||||
import ru.ulstu.user.model.DiagramElement;
|
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
import ru.ulstu.user.model.UserDto;
|
import ru.ulstu.user.model.UserDto;
|
||||||
import ru.ulstu.user.model.UserListDto;
|
import ru.ulstu.user.model.UserListDto;
|
||||||
@ -44,10 +44,10 @@ import ru.ulstu.user.repository.UserRoleRepository;
|
|||||||
import ru.ulstu.user.util.UserUtils;
|
import ru.ulstu.user.util.UserUtils;
|
||||||
|
|
||||||
import javax.mail.MessagingException;
|
import javax.mail.MessagingException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@ -361,19 +361,28 @@ public class UserService implements UserDetailsService {
|
|||||||
return userRepository.findOneByLoginIgnoreCase(login);
|
return userRepository.findOneByLoginIgnoreCase(login);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DiagramElement> getActivitiesPings(Integer userId,
|
public Map<String, Integer> getActivitiesPings(Integer userId,
|
||||||
String activity) {
|
String activityName) {
|
||||||
List<Ping> pings = pingService.getPings(userId, activity);
|
User user = null;
|
||||||
List<DiagramElement> diagramElements = new ArrayList<>();
|
if (userId != null) {
|
||||||
|
user = findById(userId);
|
||||||
|
}
|
||||||
|
Map<String, Integer> activitiesPings = new HashMap<>();
|
||||||
|
|
||||||
for (Ping ping:pings) {
|
for (Ping ping : pingService.getPings(activityName)) {
|
||||||
DiagramElement diagramElement = diagramElements.stream().filter(element -> element.getUser() == ping.getUser()).findFirst().orElse(null);
|
UserActivity activity = ping.getActivity();
|
||||||
if(diagramElement == null) {
|
|
||||||
diagramElement = new DiagramElement(ping.getUser());
|
if (user != null && !activity.getActivityUsers().contains(user)) {
|
||||||
diagramElements.add(diagramElement);
|
continue;
|
||||||
}
|
}
|
||||||
diagramElement.incrementActivity(ping);
|
|
||||||
|
if (activitiesPings.containsKey(activity.getTitle())) {
|
||||||
|
activitiesPings.put(activity.getTitle(), activitiesPings.get(activity.getTitle()) + 1);
|
||||||
|
} else {
|
||||||
|
activitiesPings.put(activity.getTitle(), 1);
|
||||||
}
|
}
|
||||||
return diagramElements;
|
|
||||||
|
}
|
||||||
|
return activitiesPings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/main/resources/mail_templates/pingsInfoWeekEmail.html
Normal file
23
src/main/resources/mail_templates/pingsInfoWeekEmail.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<title>Уведомление о создании статьи</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||||
|
<link rel="shortcut icon" th:href="@{|${baseUrl}/favicon.ico|}"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>
|
||||||
|
Уважаемый(ая) <span th:text="${user.firstName + ' ' + user.lastName}">Ivan Ivanov</span>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Вы были отмечены в следующих задачах:
|
||||||
|
</p>
|
||||||
|
<p th:each="ping : ${pings}" th:text="${ping.getActivity().getTitle() + ' ' + ping.getDate()}">
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Regards,
|
||||||
|
<br/>
|
||||||
|
<em>NG-tracker.</em>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -225,3 +225,19 @@ function getUrlVar(key) {
|
|||||||
var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search);
|
var result = new RegExp(key + "=([^&]*)", "i").exec(window.location.search);
|
||||||
return result && decodeURIComponent(result[1]) || "";
|
return result && decodeURIComponent(result[1]) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendPing(field, url) {
|
||||||
|
id = document.getElementById(field).value
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url:url + `?${field}=` + id,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
method: "POST",
|
||||||
|
success: function() {
|
||||||
|
showFeedbackMessage("Ping был отправлен", MessageTypesEnum.SUCCESS)
|
||||||
|
},
|
||||||
|
error: function(errorData) {
|
||||||
|
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
@ -130,28 +130,22 @@ function drawChart() {
|
|||||||
userId = $('#author :selected').val()
|
userId = $('#author :selected').val()
|
||||||
activity = $('#activity :selected').val()
|
activity = $('#activity :selected').val()
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url:`/api/1.0/users/activities?userId=${userId}&activity=${activity}`,
|
url:`/api/1.0/users/activities/pings?userId=${userId}&activity=${activity}`,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
if (response.data.length == 0) {
|
if (response.data.length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(userId) {
|
array = [['Активности', 'Количество']]
|
||||||
array = [['Активность', 'Количество'],
|
|
||||||
['Конференции', response.data[0].conferences],
|
Object.keys(response.data).forEach(function(key) {
|
||||||
['Статьи', response.data[0].papers],
|
console.table('Key : ' + key + ', Value : ' + response.data[key])
|
||||||
['Проекты', response.data[0].projects],
|
array.push([key, response.data[key]])
|
||||||
['Гранты', response.data[0].grants]]
|
|
||||||
} else {
|
|
||||||
array = [['Пользователи', 'Количество']]
|
|
||||||
response.data.forEach(function(element) {
|
|
||||||
array.push([element.user.firstName, element[`${activity}`]])
|
|
||||||
})
|
})
|
||||||
}
|
|
||||||
var data = google.visualization.arrayToDataTable(array);
|
var data = google.visualization.arrayToDataTable(array);
|
||||||
var options = {
|
var options = {
|
||||||
title: 'Активность',
|
title: 'Активности',
|
||||||
is3D: true,
|
is3D: true,
|
||||||
pieResidueSliceLabel: 'Остальное'
|
pieResidueSliceLabel: 'Остальное'
|
||||||
};
|
};
|
||||||
|
@ -200,7 +200,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button id="pingButton" class="btn btn-primary text-uppercase"
|
<button id="pingButton" class="btn btn-primary text-uppercase"
|
||||||
type="button" onclick="sendPing()">
|
type="button" onclick="sendPing('grantId', '/grants/ping')">
|
||||||
Ping авторам
|
Ping авторам
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -333,22 +333,6 @@
|
|||||||
var lid = $("#leaderId option:selected").val();
|
var lid = $("#leaderId option:selected").val();
|
||||||
$("#authors [value='" + lid + "']").attr("disabled", "disabled");
|
$("#authors [value='" + lid + "']").attr("disabled", "disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendPing() {
|
|
||||||
id = document.getElementById("grantId").value
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url:"/grants/ping?grantId=" + id,
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
method: "POST",
|
|
||||||
success: function() {
|
|
||||||
showFeedbackMessage("Пароль был обновлен", MessageTypesEnum.SUCCESS)
|
|
||||||
},
|
|
||||||
error: function(errorData) {
|
|
||||||
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -326,7 +326,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button id="pingButton" class="btn btn-primary text-uppercase"
|
<button id="pingButton" class="btn btn-primary text-uppercase"
|
||||||
type="button" onclick="sendPing()">
|
type="button" onclick="sendPing('paperId', '/api/1.0/papers/ping')">
|
||||||
Ping авторам
|
Ping авторам
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -562,21 +562,6 @@
|
|||||||
$(this).autocomplete("search");
|
$(this).autocomplete("search");
|
||||||
});
|
});
|
||||||
|
|
||||||
function sendPing() {
|
|
||||||
id = document.getElementById("paperId").value
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
url:"/api/1.0/papers/ping?paperId=" + id,
|
|
||||||
contentType: "application/json; charset=utf-8",
|
|
||||||
method: "POST",
|
|
||||||
success: function() {
|
|
||||||
showFeedbackMessage("Пароль был обновлен", MessageTypesEnum.SUCCESS)
|
|
||||||
},
|
|
||||||
error: function(errorData) {
|
|
||||||
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/*]]>*/
|
/*]]>*/
|
||||||
</script>
|
</script>
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button id="pingButton" class="btn btn-primary text-uppercase"
|
<button id="pingButton" class="btn btn-primary text-uppercase"
|
||||||
type="button" onclick="sendPing()">
|
type="button" onclick="sendPing('projectId', '/projects/ping')">
|
||||||
Ping авторам
|
Ping авторам
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -157,7 +157,7 @@
|
|||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
success: function() {
|
success: function() {
|
||||||
showFeedbackMessage("Пароль был обновлен", MessageTypesEnum.SUCCESS)
|
showFeedbackMessage("Ping был отправлен", MessageTypesEnum.SUCCESS)
|
||||||
},
|
},
|
||||||
error: function(errorData) {
|
error: function(errorData) {
|
||||||
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en"
|
|
||||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
|
||||||
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
|
|
||||||
<head>
|
|
||||||
<link rel="stylesheet" href="../css/grant.css"/>
|
|
||||||
<script src="https://www.google.com/jsapi"></script>
|
|
||||||
<script src="/js/users.js"></script>
|
|
||||||
<script src="/js/core.js"></script>
|
|
||||||
<script>
|
|
||||||
google.load('visualization', '1.0', {'packages':['corechart']});
|
|
||||||
google.setOnLoadCallback(drawChart);
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
|
|
||||||
<div class="container" layout:fragment="content">
|
|
||||||
<section id="ewrq">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-lg-12 text-center">
|
|
||||||
<h2 class="section-heading text-uppercase">Личный кабинет</h2>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3 col-sm-12">
|
|
||||||
<div class="filter">
|
|
||||||
<h5>Фильтр:</h5>
|
|
||||||
<select class="form-control" id="author"
|
|
||||||
onchange="drawChart();">
|
|
||||||
<option value="">Все авторы</option>
|
|
||||||
<option th:each="user: ${allUsers}" th:value="${user.id}"
|
|
||||||
th:text="${user.lastName}">lastName
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<br />
|
|
||||||
<select class="form-control" id="activity"
|
|
||||||
onchange="drawChart();">
|
|
||||||
<option value="">Все активности</option>
|
|
||||||
<option th:each="activity: ${allActivities}" th:value="${activity}"
|
|
||||||
th:text="${activity}">year
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div id="air" style="width: 500px; height: 400px;"></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
53
src/main/resources/templates/users/pings.html
Normal file
53
src/main/resources/templates/users/pings.html
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||||
|
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../css/grant.css"/>
|
||||||
|
<script src="https://www.google.com/jsapi"></script>
|
||||||
|
<script src="/js/users.js"></script>
|
||||||
|
<script src="/js/core.js"></script>
|
||||||
|
<script>
|
||||||
|
google.load('visualization', '1.0', {'packages':['corechart']});
|
||||||
|
google.setOnLoadCallback(drawChart);
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="container" layout:fragment="content">
|
||||||
|
<section id="ewrq">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12 text-center">
|
||||||
|
<h2 class="section-heading text-uppercase">Ping активности</h2>
|
||||||
|
</div>
|
||||||
|
<div id="air" style="width: 500px; height: 400px;" class="col-md-9 col-sm-12"></div>
|
||||||
|
<div class="col-md-3 col-sm-12">
|
||||||
|
<div class="filter">
|
||||||
|
<h5>Фильтр:</h5>
|
||||||
|
<select class="form-control" id="author"
|
||||||
|
onchange="drawChart();">
|
||||||
|
<option value="">Все авторы</option>
|
||||||
|
<option th:each="user: ${allUsers}" th:value="${user.id}"
|
||||||
|
th:text="${user.lastName}">lastName
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<br/>
|
||||||
|
<select class="form-control" id="activity"
|
||||||
|
onchange="drawChart();">
|
||||||
|
<option value="">Все активности</option>
|
||||||
|
<option th:each="activity: ${allActivities}" th:value="${activity.key}"
|
||||||
|
th:text="${activity.value}">
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -4,13 +4,6 @@
|
|||||||
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
|
layout:decorator="default" xmlns:th="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/html">
|
||||||
<head>
|
<head>
|
||||||
<link rel="stylesheet" href="../css/grant.css"/>
|
<link rel="stylesheet" href="../css/grant.css"/>
|
||||||
<script src="js/users.js"></script>
|
|
||||||
<script src="js/core.js"></script>
|
|
||||||
<script src="https://www.google.com/jsapi"></script>
|
|
||||||
<script>
|
|
||||||
google.load('visualization', '1.0', {'packages':['corechart']});
|
|
||||||
google.setOnLoadCallback(drawChart);
|
|
||||||
</script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user