WIP: Resolve "Статистика по активностям" #232
@ -0,0 +1,17 @@
|
|||||||
|
package ru.ulstu.activity.controller;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import ru.ulstu.activity.service.ActivityService;
|
||||||
|
|
||||||
|
@Controller()
|
||||||
|
@RequestMapping(value = "/activities")
|
||||||
|
public class ActivityController {
|
||||||
|
private ActivityService activityService;
|
||||||
|
|
||||||
|
public ActivityController(ActivityService activityService) {
|
||||||
|
this.activityService = activityService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
81
src/main/java/ru/ulstu/activity/model/Activity.java
Normal file
81
src/main/java/ru/ulstu/activity/model/Activity.java
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
package ru.ulstu.activity.model;
|
||||||
|
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import ru.ulstu.core.model.BaseEntity;
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.EnumType;
|
||||||
|
import javax.persistence.Enumerated;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.ManyToOne;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import javax.persistence.Temporal;
|
||||||
|
import javax.persistence.TemporalType;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "activity")
|
||||||
|
public class Activity extends BaseEntity {
|
||||||
|
|
||||||
|
public enum ActivityState {
|
||||||
|
TOOK_IN_WORK("Взято в работу"),
|
||||||
|
COMPLETED("Выполнено");
|
||||||
|
|
||||||
|
private String statusName;
|
||||||
|
|
||||||
|
ActivityState(String statusName) {
|
||||||
|
this.statusName = statusName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatusName() {
|
||||||
|
return this.statusName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManyToOne()
|
||||||
|
@JoinColumn(name = "user_id")
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
@Temporal(value = TemporalType.TIMESTAMP)
|
||||||
|
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||||
|
private Date date;
|
||||||
|
|
||||||
|
@Enumerated(value = EnumType.STRING)
|
||||||
|
@Column(name = "state")
|
||||||
|
private ActivityState activityState;
|
||||||
|
|
||||||
|
public Activity(User user, ActivityState activityState) {
|
||||||
|
this.user = user;
|
||||||
|
this.date = new Date();
|
||||||
|
this.activityState = activityState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Activity() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public User getUser() {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUser(User user) {
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDate(Date date) {
|
||||||
|
this.date = date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivityState getActivityState() {
|
||||||
|
return activityState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivityState(ActivityState activityState) {
|
||||||
|
this.activityState = activityState;
|
||||||
|
}
|
||||||
|
}
|
38
src/main/java/ru/ulstu/activity/model/ActivityElement.java
Normal file
38
src/main/java/ru/ulstu/activity/model/ActivityElement.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package ru.ulstu.activity.model;
|
||||||
|
|
||||||
|
public class ActivityElement {
|
||||||
|
private int startedCount = 0;
|
||||||
|
private int completedCount = 0;
|
||||||
|
|
||||||
|
public ActivityElement() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivityElement(int startedCount, int completedCount) {
|
||||||
|
this.startedCount = startedCount;
|
||||||
|
this.completedCount = completedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStartedCount() {
|
||||||
|
return startedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartedCount(int startedCount) {
|
||||||
|
this.startedCount = startedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCompletedCount() {
|
||||||
|
return completedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCompletedCount(int completedCount) {
|
||||||
|
this.completedCount = completedCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementStartedCount() {
|
||||||
|
this.startedCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void incrementCompletedCount() {
|
||||||
|
this.completedCount++;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package ru.ulstu.activity.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import ru.ulstu.activity.model.Activity;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ActivityRepository extends JpaRepository<Activity, Integer> {
|
||||||
|
|
||||||
|
@Query("SELECT a FROM Activity a WHERE (:userId IS NULL OR a.user.id = :userId) " +
|
||||||
|
"AND (CAST(:dateFrom AS date) IS NULL OR :dateFrom < a.date) " +
|
||||||
|
"AND (CAST(:dateTo AS date) IS NULL OR :dateTo > a.date)")
|
||||||
|
List<Activity> getByUserAndDateInterval(@Param("userId") Integer userId,
|
||||||
|
@Param("dateFrom") Date dateFrom,
|
||||||
|
@Param("dateTo") Date dateTo);
|
||||||
|
}
|
56
src/main/java/ru/ulstu/activity/service/ActivityService.java
Normal file
56
src/main/java/ru/ulstu/activity/service/ActivityService.java
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
package ru.ulstu.activity.service;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.ulstu.activity.model.Activity;
|
||||||
|
import ru.ulstu.activity.model.ActivityElement;
|
||||||
|
import ru.ulstu.activity.repository.ActivityRepository;
|
||||||
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class ActivityService {
|
||||||
|
private ActivityRepository activityRepository;
|
||||||
|
|
||||||
|
public ActivityService(ActivityRepository activityRepository) {
|
||||||
|
this.activityRepository = activityRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createActivity(List<User> users, Activity.ActivityState state) {
|
||||||
|
List<Activity> activities = new ArrayList<>();
|
||||||
|
for (User user : users) {
|
||||||
|
activities.add(new Activity(user, state));
|
||||||
|
}
|
||||||
|
activityRepository.save(activities);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, ActivityElement> getUsersActivity(Integer userId, Date dateFrom, Date dateTo) {
|
||||||
|
List<Activity> activities = activityRepository.getByUserAndDateInterval(userId, dateFrom, dateTo);
|
||||||
|
Map<String, ActivityElement> dateActivities = new HashMap<>();
|
||||||
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
for (Activity activity : activities) {
|
||||||
|
String dt = formatter.format(activity.getDate());
|
||||||
|
ActivityElement element;
|
||||||
|
if (!dateActivities.containsKey(dt)) {
|
||||||
|
element = new ActivityElement();
|
||||||
|
} else {
|
||||||
|
element = dateActivities.get(dt);
|
||||||
|
}
|
||||||
|
switch (activity.getActivityState()) {
|
||||||
|
case TOOK_IN_WORK:
|
||||||
|
element.incrementStartedCount();
|
||||||
|
break;
|
||||||
|
case COMPLETED:
|
||||||
|
element.incrementCompletedCount();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dateActivities.put(dt, element);
|
||||||
|
}
|
||||||
|
return dateActivities;
|
||||||
|
}
|
||||||
|
}
|
@ -14,7 +14,7 @@ public class AuthFailureHandler implements AuthenticationFailureHandler {
|
|||||||
@Override
|
@Override
|
||||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||||
AuthenticationException ex) throws IOException {
|
AuthenticationException ex) throws IOException {
|
||||||
if (ex.getClass() == UserBlockedException.class) {
|
if (ex.getCause() instanceof UserBlockedException) {
|
||||||
response.sendRedirect("/users/block");
|
response.sendRedirect("/users/block");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import ru.ulstu.file.model.FileData;
|
|||||||
import ru.ulstu.paper.model.Paper;
|
import ru.ulstu.paper.model.Paper;
|
||||||
import ru.ulstu.project.model.Project;
|
import ru.ulstu.project.model.Project;
|
||||||
import ru.ulstu.timeline.model.Event;
|
import ru.ulstu.timeline.model.Event;
|
||||||
|
import ru.ulstu.activity.model.Activity;
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
@ -173,6 +174,17 @@ public class Grant extends BaseEntity implements UserActivity, EventSource {
|
|||||||
return getAuthors();
|
return getAuthors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Activity.ActivityState getCommonActivityState() {
|
||||||
|
switch (this.status) {
|
||||||
|
case IN_WORK:
|
||||||
|
return Activity.ActivityState.TOOK_IN_WORK;
|
||||||
|
case COMPLETED:
|
||||||
|
return Activity.ActivityState.COMPLETED;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public User getLeader() {
|
public User getLeader() {
|
||||||
return leader;
|
return leader;
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
|
import ru.ulstu.activity.service.ActivityService;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.deadline.service.DeadlineService;
|
import ru.ulstu.deadline.service.DeadlineService;
|
||||||
import ru.ulstu.file.model.FileDataDto;
|
import ru.ulstu.file.model.FileDataDto;
|
||||||
@ -26,6 +27,7 @@ import ru.ulstu.user.service.UserService;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -53,6 +55,7 @@ public class GrantService extends BaseService {
|
|||||||
private final GrantNotificationService grantNotificationService;
|
private final GrantNotificationService grantNotificationService;
|
||||||
private final KiasService kiasService;
|
private final KiasService kiasService;
|
||||||
private final PingService pingService;
|
private final PingService pingService;
|
||||||
|
private final ActivityService activityService;
|
||||||
|
|
||||||
public GrantService(GrantRepository grantRepository,
|
public GrantService(GrantRepository grantRepository,
|
||||||
FileService fileService,
|
FileService fileService,
|
||||||
@ -63,7 +66,8 @@ public class GrantService extends BaseService {
|
|||||||
EventService eventService,
|
EventService eventService,
|
||||||
GrantNotificationService grantNotificationService,
|
GrantNotificationService grantNotificationService,
|
||||||
KiasService kiasService,
|
KiasService kiasService,
|
||||||
PingService pingService) {
|
PingService pingService,
|
||||||
|
ActivityService activityService) {
|
||||||
this.grantRepository = grantRepository;
|
this.grantRepository = grantRepository;
|
||||||
this.kiasService = kiasService;
|
this.kiasService = kiasService;
|
||||||
this.baseRepository = grantRepository;
|
this.baseRepository = grantRepository;
|
||||||
@ -75,6 +79,7 @@ public class GrantService extends BaseService {
|
|||||||
this.eventService = eventService;
|
this.eventService = eventService;
|
||||||
this.grantNotificationService = grantNotificationService;
|
this.grantNotificationService = grantNotificationService;
|
||||||
this.pingService = pingService;
|
this.pingService = pingService;
|
||||||
|
this.activityService = activityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GrantDto getExistGrantById(Integer id) {
|
public GrantDto getExistGrantById(Integer id) {
|
||||||
@ -95,6 +100,7 @@ public class GrantService extends BaseService {
|
|||||||
Grant newGrant = copyFromDto(new Grant(), grantDto);
|
Grant newGrant = copyFromDto(new Grant(), grantDto);
|
||||||
newGrant = grantRepository.save(newGrant);
|
newGrant = grantRepository.save(newGrant);
|
||||||
eventService.createFromObject(newGrant, Collections.emptyList(), false, "гранта");
|
eventService.createFromObject(newGrant, Collections.emptyList(), false, "гранта");
|
||||||
|
activityService.createActivity(new ArrayList<>(newGrant.getAuthors()), newGrant.getCommonActivityState());
|
||||||
grantNotificationService.sendCreateNotification(newGrant);
|
grantNotificationService.sendCreateNotification(newGrant);
|
||||||
return newGrant;
|
return newGrant;
|
||||||
}
|
}
|
||||||
@ -137,6 +143,7 @@ public class GrantService extends BaseService {
|
|||||||
Grant grant = findById(grantDto.getId());
|
Grant grant = findById(grantDto.getId());
|
||||||
Set<User> oldAuthors = new HashSet<>(grant.getAuthors());
|
Set<User> oldAuthors = new HashSet<>(grant.getAuthors());
|
||||||
User oldLeader = grant.getLeader();
|
User oldLeader = grant.getLeader();
|
||||||
|
Grant.GrantStatus oldStatus = grant.getStatus();
|
||||||
for (FileDataDto file : grantDto.getFiles().stream()
|
for (FileDataDto file : grantDto.getFiles().stream()
|
||||||
.filter(f -> f.isDeleted() && f.getId() != null)
|
.filter(f -> f.isDeleted() && f.getId() != null)
|
||||||
.collect(toList())) {
|
.collect(toList())) {
|
||||||
@ -158,6 +165,9 @@ public class GrantService extends BaseService {
|
|||||||
if (grant.getLeader() != oldLeader) {
|
if (grant.getLeader() != oldLeader) {
|
||||||
grantNotificationService.sendLeaderChangeNotification(grant, oldLeader);
|
grantNotificationService.sendLeaderChangeNotification(grant, oldLeader);
|
||||||
}
|
}
|
||||||
|
if (grant.getStatus() != oldStatus) {
|
||||||
|
activityService.createActivity(new ArrayList<>(grant.getAuthors()), grant.getCommonActivityState());
|
||||||
|
}
|
||||||
eventService.updateGrantDeadlines(grant);
|
eventService.updateGrantDeadlines(grant);
|
||||||
return grant.getId();
|
return grant.getId();
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ 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.timeline.model.Event;
|
import ru.ulstu.timeline.model.Event;
|
||||||
|
import ru.ulstu.activity.model.Activity;
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
@ -323,4 +324,15 @@ public class Paper extends BaseEntity implements UserActivity, EventSource {
|
|||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, latexText, conferences, grants);
|
return Objects.hash(super.hashCode(), title, status, type, createDate, updateDate, deadlines, comment, url, locked, events, files, authors, latexText, conferences, grants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Activity.ActivityState getCommonActivityState() {
|
||||||
|
switch (this.status) {
|
||||||
|
case ON_PREPARATION:
|
||||||
|
return Activity.ActivityState.TOOK_IN_WORK;
|
||||||
|
case COMPLETED:
|
||||||
|
return Activity.ActivityState.COMPLETED;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package ru.ulstu.paper.service;
|
|||||||
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;
|
||||||
|
import ru.ulstu.activity.service.ActivityService;
|
||||||
import ru.ulstu.deadline.model.Deadline;
|
import ru.ulstu.deadline.model.Deadline;
|
||||||
import ru.ulstu.deadline.service.DeadlineService;
|
import ru.ulstu.deadline.service.DeadlineService;
|
||||||
import ru.ulstu.file.model.FileDataDto;
|
import ru.ulstu.file.model.FileDataDto;
|
||||||
@ -22,6 +23,7 @@ import ru.ulstu.user.service.UserService;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -56,6 +58,7 @@ public class PaperService {
|
|||||||
private final EventService eventService;
|
private final EventService eventService;
|
||||||
private final ReferenceRepository referenceRepository;
|
private final ReferenceRepository referenceRepository;
|
||||||
private final PingService pingService;
|
private final PingService pingService;
|
||||||
|
private final ActivityService activityService;
|
||||||
|
|
||||||
public PaperService(PaperRepository paperRepository,
|
public PaperService(PaperRepository paperRepository,
|
||||||
ReferenceRepository referenceRepository,
|
ReferenceRepository referenceRepository,
|
||||||
@ -64,7 +67,8 @@ public class PaperService {
|
|||||||
UserService userService,
|
UserService userService,
|
||||||
DeadlineService deadlineService,
|
DeadlineService deadlineService,
|
||||||
EventService eventService,
|
EventService eventService,
|
||||||
PingService pingService) {
|
PingService pingService,
|
||||||
|
ActivityService activityService) {
|
||||||
this.paperRepository = paperRepository;
|
this.paperRepository = paperRepository;
|
||||||
this.referenceRepository = referenceRepository;
|
this.referenceRepository = referenceRepository;
|
||||||
this.fileService = fileService;
|
this.fileService = fileService;
|
||||||
@ -73,6 +77,7 @@ public class PaperService {
|
|||||||
this.deadlineService = deadlineService;
|
this.deadlineService = deadlineService;
|
||||||
this.eventService = eventService;
|
this.eventService = eventService;
|
||||||
this.pingService = pingService;
|
this.pingService = pingService;
|
||||||
|
this.activityService = activityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Paper> findAll() {
|
public List<Paper> findAll() {
|
||||||
@ -201,6 +206,7 @@ public class PaperService {
|
|||||||
|
|
||||||
if (paper.getStatus() != oldStatus) {
|
if (paper.getStatus() != oldStatus) {
|
||||||
paperNotificationService.statusChangeNotification(paper, oldStatus);
|
paperNotificationService.statusChangeNotification(paper, oldStatus);
|
||||||
|
activityService.createActivity(new ArrayList<>(paper.getAuthors()), paper.getCommonActivityState());
|
||||||
}
|
}
|
||||||
|
|
||||||
return paper.getId();
|
return paper.getId();
|
||||||
@ -241,7 +247,9 @@ public class PaperService {
|
|||||||
paper = paperRepository.save(paper);
|
paper = paperRepository.save(paper);
|
||||||
|
|
||||||
paperNotificationService.sendCreateNotification(paper);
|
paperNotificationService.sendCreateNotification(paper);
|
||||||
|
|
||||||
eventService.createFromPaper(paper);
|
eventService.createFromPaper(paper);
|
||||||
|
activityService.createActivity(new ArrayList<>(paper.getAuthors()), paper.getCommonActivityState());
|
||||||
|
|
||||||
return paper;
|
return paper;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ 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.timeline.model.Event;
|
import ru.ulstu.timeline.model.Event;
|
||||||
|
import ru.ulstu.activity.model.Activity;
|
||||||
import ru.ulstu.user.model.User;
|
import ru.ulstu.user.model.User;
|
||||||
|
|
||||||
import javax.persistence.CascadeType;
|
import javax.persistence.CascadeType;
|
||||||
@ -106,6 +107,17 @@ public class Project extends BaseEntity implements UserActivity, EventSource {
|
|||||||
event.setProject(this);
|
event.setProject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Activity.ActivityState getCommonActivityState() {
|
||||||
|
switch (this.status) {
|
||||||
|
case IN_WORK:
|
||||||
|
return Activity.ActivityState.TOOK_IN_WORK;
|
||||||
|
case CLOSED:
|
||||||
|
return Activity.ActivityState.COMPLETED;
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package ru.ulstu.project.service;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.thymeleaf.util.StringUtils;
|
import org.thymeleaf.util.StringUtils;
|
||||||
|
import ru.ulstu.activity.service.ActivityService;
|
||||||
import ru.ulstu.deadline.service.DeadlineService;
|
import ru.ulstu.deadline.service.DeadlineService;
|
||||||
import ru.ulstu.file.model.FileDataDto;
|
import ru.ulstu.file.model.FileDataDto;
|
||||||
import ru.ulstu.file.service.FileService;
|
import ru.ulstu.file.service.FileService;
|
||||||
@ -17,6 +18,7 @@ import ru.ulstu.user.model.User;
|
|||||||
import ru.ulstu.user.service.UserService;
|
import ru.ulstu.user.service.UserService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -37,14 +39,15 @@ public class ProjectService {
|
|||||||
private final EventService eventService;
|
private final EventService eventService;
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final PingService pingService;
|
private final PingService pingService;
|
||||||
|
private final ActivityService activityService;
|
||||||
public ProjectService(ProjectRepository projectRepository,
|
public ProjectService(ProjectRepository projectRepository,
|
||||||
DeadlineService deadlineService,
|
DeadlineService deadlineService,
|
||||||
GrantRepository grantRepository,
|
GrantRepository grantRepository,
|
||||||
FileService fileService,
|
FileService fileService,
|
||||||
EventService eventService,
|
EventService eventService,
|
||||||
UserService userService,
|
UserService userService,
|
||||||
PingService pingService) {
|
PingService pingService,
|
||||||
|
ActivityService activityService) {
|
||||||
this.projectRepository = projectRepository;
|
this.projectRepository = projectRepository;
|
||||||
this.deadlineService = deadlineService;
|
this.deadlineService = deadlineService;
|
||||||
this.grantRepository = grantRepository;
|
this.grantRepository = grantRepository;
|
||||||
@ -52,6 +55,7 @@ public class ProjectService {
|
|||||||
this.eventService = eventService;
|
this.eventService = eventService;
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.pingService = pingService;
|
this.pingService = pingService;
|
||||||
|
this.activityService = activityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Project> findAll() {
|
public List<Project> findAll() {
|
||||||
@ -77,12 +81,17 @@ public class ProjectService {
|
|||||||
Project newProject = copyFromDto(new Project(), projectDto);
|
Project newProject = copyFromDto(new Project(), projectDto);
|
||||||
newProject = projectRepository.save(newProject);
|
newProject = projectRepository.save(newProject);
|
||||||
eventService.createFromObject(newProject, Collections.emptyList(), false, "проекта");
|
eventService.createFromObject(newProject, Collections.emptyList(), false, "проекта");
|
||||||
|
activityService.createActivity(new ArrayList<>(newProject.getExecutors()), newProject.getCommonActivityState());
|
||||||
|
|
||||||
return newProject;
|
return newProject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public Project update(ProjectDto projectDto) throws IOException {
|
public Project update(ProjectDto projectDto) throws IOException {
|
||||||
Project project = projectRepository.findOne(projectDto.getId());
|
Project project = projectRepository.findOne(projectDto.getId());
|
||||||
|
if (project.getStatus() != projectDto.getStatus()) {
|
||||||
|
activityService.createActivity(new ArrayList<>(project.getExecutors()), project.getCommonActivityState());
|
||||||
|
}
|
||||||
projectRepository.save(copyFromDto(project, projectDto));
|
projectRepository.save(copyFromDto(project, projectDto));
|
||||||
eventService.updateProjectDeadlines(project);
|
eventService.updateProjectDeadlines(project);
|
||||||
for (FileDataDto file : projectDto.getFiles().stream()
|
for (FileDataDto file : projectDto.getFiles().stream()
|
||||||
|
@ -2,6 +2,7 @@ package ru.ulstu.user.controller;
|
|||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.security.access.annotation.Secured;
|
import org.springframework.security.access.annotation.Secured;
|
||||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@ -12,6 +13,7 @@ import org.springframework.web.bind.annotation.RequestBody;
|
|||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import ru.ulstu.activity.service.ActivityService;
|
||||||
import ru.ulstu.configuration.Constants;
|
import ru.ulstu.configuration.Constants;
|
||||||
import ru.ulstu.core.model.response.PageableItems;
|
import ru.ulstu.core.model.response.PageableItems;
|
||||||
import ru.ulstu.core.model.response.Response;
|
import ru.ulstu.core.model.response.Response;
|
||||||
@ -19,6 +21,7 @@ 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.activity.model.ActivityElement;
|
||||||
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;
|
||||||
@ -32,6 +35,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 javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static ru.ulstu.user.controller.UserController.URL;
|
import static ru.ulstu.user.controller.UserController.URL;
|
||||||
@ -55,16 +60,19 @@ public class UserController extends OdinController<UserListDto, UserDto> {
|
|||||||
private final UserSessionService userSessionService;
|
private final UserSessionService userSessionService;
|
||||||
private final OdinService<UserRoleDto, UserRoleDto> odinRolesService;
|
private final OdinService<UserRoleDto, UserRoleDto> odinRolesService;
|
||||||
private final OdinService<UserSessionListDto, OdinVoid> odinSessionsService;
|
private final OdinService<UserSessionListDto, OdinVoid> odinSessionsService;
|
||||||
|
private final ActivityService activityService;
|
||||||
|
|
||||||
public UserController(UserService userService,
|
public UserController(UserService userService,
|
||||||
UserSessionService userSessionService,
|
UserSessionService userSessionService,
|
||||||
OdinService<UserRoleDto, UserRoleDto> odinRolesService,
|
OdinService<UserRoleDto, UserRoleDto> odinRolesService,
|
||||||
OdinService<UserSessionListDto, OdinVoid> odinSessionsService) {
|
OdinService<UserSessionListDto, OdinVoid> odinSessionsService,
|
||||||
|
ActivityService activityService) {
|
||||||
super(UserListDto.class, UserDto.class);
|
super(UserListDto.class, UserDto.class);
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.userSessionService = userSessionService;
|
this.userSessionService = userSessionService;
|
||||||
this.odinRolesService = odinRolesService;
|
this.odinRolesService = odinRolesService;
|
||||||
this.odinSessionsService = odinSessionsService;
|
this.odinSessionsService = odinSessionsService;
|
||||||
|
this.activityService = activityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping(ROLES_URL)
|
@GetMapping(ROLES_URL)
|
||||||
@ -180,4 +188,11 @@ public class UserController extends OdinController<UserListDto, UserDto> {
|
|||||||
public void blockUser(@RequestParam("userId") Integer userId) {
|
public void blockUser(@RequestParam("userId") Integer userId) {
|
||||||
userService.blockUser(userId);
|
userService.blockUser(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/activities")
|
||||||
|
public Response<Map<String, ActivityElement>> getActivitiesList(@RequestParam("userId") Integer userId,
|
||||||
|
@RequestParam("dateFrom") @DateTimeFormat(pattern = "yyyy-MM-dd") Date dateFrom,
|
||||||
|
@RequestParam("dateTo") @DateTimeFormat(pattern = "yyyy-MM-dd") Date dateTo) {
|
||||||
|
return new Response<>(activityService.getUsersActivity(userId, dateFrom, dateTo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,4 +78,8 @@ public class UserMvcController extends OdinController<UserListDto, UserDto> {
|
|||||||
@GetMapping("/block")
|
@GetMapping("/block")
|
||||||
public void getBlock() {
|
public void getBlock() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/activities")
|
||||||
|
public void getActivities() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import ru.ulstu.user.model.UserResetPasswordDto;
|
|||||||
import ru.ulstu.user.model.UserRole;
|
import ru.ulstu.user.model.UserRole;
|
||||||
import ru.ulstu.user.model.UserRoleConstants;
|
import ru.ulstu.user.model.UserRoleConstants;
|
||||||
import ru.ulstu.user.model.UserRoleDto;
|
import ru.ulstu.user.model.UserRoleDto;
|
||||||
|
import ru.ulstu.activity.repository.ActivityRepository;
|
||||||
import ru.ulstu.user.repository.UserRepository;
|
import ru.ulstu.user.repository.UserRepository;
|
||||||
import ru.ulstu.user.repository.UserRoleRepository;
|
import ru.ulstu.user.repository.UserRoleRepository;
|
||||||
import ru.ulstu.user.util.UserUtils;
|
import ru.ulstu.user.util.UserUtils;
|
||||||
@ -78,6 +79,7 @@ public class UserService implements UserDetailsService {
|
|||||||
private final TimetableService timetableService;
|
private final TimetableService timetableService;
|
||||||
private final ConferenceService conferenceService;
|
private final ConferenceService conferenceService;
|
||||||
private final UserSessionService userSessionService;
|
private final UserSessionService userSessionService;
|
||||||
|
private final ActivityRepository activityRepository;
|
||||||
private final PingService pingService;
|
private final PingService pingService;
|
||||||
|
|
||||||
public UserService(UserRepository userRepository,
|
public UserService(UserRepository userRepository,
|
||||||
@ -88,7 +90,8 @@ public class UserService implements UserDetailsService {
|
|||||||
ApplicationProperties applicationProperties,
|
ApplicationProperties applicationProperties,
|
||||||
@Lazy PingService pingService,
|
@Lazy PingService pingService,
|
||||||
@Lazy ConferenceService conferenceRepository,
|
@Lazy ConferenceService conferenceRepository,
|
||||||
@Lazy UserSessionService userSessionService) throws ParseException {
|
@Lazy UserSessionService userSessionService,
|
||||||
|
ActivityRepository activityRepository) throws ParseException {
|
||||||
this.userRepository = userRepository;
|
this.userRepository = userRepository;
|
||||||
this.passwordEncoder = passwordEncoder;
|
this.passwordEncoder = passwordEncoder;
|
||||||
this.userRoleRepository = userRoleRepository;
|
this.userRoleRepository = userRoleRepository;
|
||||||
@ -98,6 +101,7 @@ public class UserService implements UserDetailsService {
|
|||||||
this.conferenceService = conferenceRepository;
|
this.conferenceService = conferenceRepository;
|
||||||
this.timetableService = new TimetableService();
|
this.timetableService = new TimetableService();
|
||||||
this.userSessionService = userSessionService;
|
this.userSessionService = userSessionService;
|
||||||
|
this.activityRepository = activityRepository;
|
||||||
this.pingService = pingService;
|
this.pingService = pingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
src/main/resources/db/changelog-20190603_000002-schema.xml
Normal file
17
src/main/resources/db/changelog-20190603_000002-schema.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||||
|
<changeSet author="arefyev" id="20190603_000000-3">
|
||||||
|
<createTable tableName="activity">
|
||||||
|
<column name="id" type="integer"/>
|
||||||
|
<column name="user_id" type="integer"/>
|
||||||
|
<column name="version" type="integer"/>
|
||||||
|
<column name="date" type="timestamp"/>
|
||||||
|
<column name="state" type="varchar(255)"/>
|
||||||
|
</createTable>
|
||||||
|
<addForeignKeyConstraint baseTableName="activity" baseColumnNames="user_id"
|
||||||
|
constraintName="fk_activity_user" referencedTableName="users"
|
||||||
|
referencedColumnNames="id"/>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
@ -54,4 +54,5 @@
|
|||||||
<include file="db/changelog-20190601_000001-schema.xml"/>
|
<include file="db/changelog-20190601_000001-schema.xml"/>
|
||||||
<include file="db/changelog-20190605_000000-schema.xml"/>
|
<include file="db/changelog-20190605_000000-schema.xml"/>
|
||||||
<include file="db/changelog-20190607_000002-schema.xml"/>
|
<include file="db/changelog-20190607_000002-schema.xml"/>
|
||||||
|
<include file="db/changelog-20190603_000002-schema.xml"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
@ -170,4 +170,39 @@ function drawChart() {
|
|||||||
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawActivitiesChart() {
|
||||||
|
userId = $('#author :selected').val()
|
||||||
|
dateFrom = $('#dateFrom').val()
|
||||||
|
dateTo = $('#dateTo').val()
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url:`/api/1.0/users/activities?userId=${userId}&dateFrom=${dateFrom}&dateTo=${dateTo}`,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
method: "GET",
|
||||||
|
success: function(response) {
|
||||||
|
if (response.data.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
kk = response.data;
|
||||||
|
array = [['Активности', 'Количество начатых', 'Количество законченных']]
|
||||||
|
|
||||||
|
Object.keys(response.data).forEach(function(key) {
|
||||||
|
console.table('Key : ' + key + ', Value : ' + response.data[key])
|
||||||
|
array.push([key, response.data[key]['startedCount'], response.data[key]['completedCount']])
|
||||||
|
})
|
||||||
|
var data = google.visualization.arrayToDataTable(array);
|
||||||
|
var options = {
|
||||||
|
title: 'Активности',
|
||||||
|
is3D: true,
|
||||||
|
pieResidueSliceLabel: 'Остальное'
|
||||||
|
};
|
||||||
|
var chart = new google.visualization.ColumnChart(document.getElementById('air'));
|
||||||
|
chart.draw(data, options);
|
||||||
|
},
|
||||||
|
error: function(errorData) {
|
||||||
|
showFeedbackMessage(errorData.responseJSON.error.message, MessageTypesEnum.WARNING)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
46
src/main/resources/templates/users/activities.html
Normal file
46
src/main/resources/templates/users/activities.html
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<!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(drawActivitiesChart);
|
||||||
|
</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 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="drawActivitiesChart();">
|
||||||
|
<option value="">Все авторы</option>
|
||||||
|
<option th:each="user: ${allUsers}" th:value="${user.id}"
|
||||||
|
th:text="${user.lastName}">lastName
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
<br/>
|
||||||
|
<input onchange="drawActivitiesChart();" type="date" id="dateFrom"/>
|
||||||
|
<input onchange="drawActivitiesChart();" type="date" id="dateTo"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user