#21 -- Add report list form

This commit is contained in:
Anton Romanov 2025-04-03 14:53:21 +04:00
parent 3546e016e1
commit 0fee0ab9ce
9 changed files with 175 additions and 12 deletions

View File

@ -2,6 +2,8 @@ package ru.ulstu.aspirant.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.aspirant.model.Aspirant;
import ru.ulstu.model.User;
public interface AspirantRepository extends JpaRepository<Aspirant, Integer> {
Aspirant findByUser(User user);
}

View File

@ -6,10 +6,10 @@ import org.springframework.stereotype.Service;
import ru.ulstu.admin.model.AspirantForm;
import ru.ulstu.aspirant.model.Aspirant;
import ru.ulstu.aspirant.repository.AspirantRepository;
import ru.ulstu.indicator.model.Course;
import ru.ulstu.indicator.model.Indicator;
import ru.ulstu.indicator.service.IndicatorService;
import ru.ulstu.user.UserUtils;
import ru.ulstu.model.User;
import ru.ulstu.user.UserService;
import java.util.List;
@ -17,11 +17,14 @@ import java.util.List;
public class AspirantService {
private final AspirantRepository aspirantRepository;
private final IndicatorService indicatorService;
private final UserService userService;
public AspirantService(AspirantRepository aspirantRepository,
IndicatorService indicatorService) {
IndicatorService indicatorService,
UserService userService) {
this.aspirantRepository = aspirantRepository;
this.indicatorService = indicatorService;
this.userService = userService;
}
public List<Aspirant> getAspirants() {
@ -40,14 +43,12 @@ public class AspirantService {
aspirantRepository.deleteById(aspirantForm.getId());
}
public Aspirant getAspirantByUser(String currentUserLogin) {
//return aspirantRepository.getAspirantByLogin();
//TODO: read aspirant
return aspirantRepository.findAll().stream().findAny().orElse(new Aspirant("default", Course.FIRST));
public Aspirant getAspirantByUser(User user) {
return aspirantRepository.findByUser(user);
}
public List<Indicator> getIndicatorsByCourse() {
Aspirant aspirant = getAspirantByUser(UserUtils.getCurrentUserLogin());
Aspirant aspirant = getAspirantByUser(userService.getCurrentUser());
return indicatorService.getIndicatorsByCourse(aspirant.getCourse());
}

View File

@ -0,0 +1,40 @@
package ru.ulstu.report.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.report.model.ReportListForm;
import ru.ulstu.report.service.ReportPeriodService;
import ru.ulstu.report.service.ReportService;
@Controller
@RequestMapping("report")
public class ReportController {
private final ReportService reportService;
private final ReportPeriodService reportPeriodService;
public ReportController(ReportService reportService,
ReportPeriodService reportPeriodService) {
this.reportService = reportService;
this.reportPeriodService = reportPeriodService;
}
@GetMapping("reportList")
public String getReportPeriods(Model model) {
model.addAttribute("reportListForm", new ReportListForm());
model.addAttribute("reportPeriods", reportPeriodService.getReportPeriods());
model.addAttribute("canCreate", false);
return "report/reportList";
}
@PostMapping("reportList")
public String getReportPeriods(ReportListForm reportListForm, Model model) {
model.addAttribute("reportListForm", reportListForm);
model.addAttribute("reportPeriods", reportPeriodService.getReportPeriods());
model.addAttribute("reports", reportService.getReports(reportListForm.getReportPeriod()));
model.addAttribute("canCreate", reportService.canCreateReport(reportListForm.getReportPeriod()));
return "report/reportList";
}
}

View File

@ -0,0 +1,13 @@
package ru.ulstu.report.model;
public class ReportListForm {
private ReportPeriod reportPeriod;
public ReportPeriod getReportPeriod() {
return reportPeriod;
}
public void setReportPeriod(ReportPeriod reportPeriod) {
this.reportPeriod = reportPeriod;
}
}

View File

@ -3,13 +3,19 @@ package ru.ulstu.report.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.aspirant.model.Aspirant;
import ru.ulstu.report.model.Report;
import ru.ulstu.report.model.ReportPeriod;
import ru.ulstu.statistic.model.RatingItem;
import java.util.List;
public interface ReportRepository extends JpaRepository<Report, Integer> {
List<Report> findAllByReportPeriod(ReportPeriod reportPeriod);
Report findByReportPeriodAndAspirant(ReportPeriod reportPeriod, Aspirant aspirant);
@Query("SELECT new ru.ulstu.statistic.model.RatingItem(r.aspirant, (SELECT cast(sum(rv.indicatorValue) AS Integer) FROM ReportValue rv WHERE rv MEMBER OF r.values)) FROM Report r JOIN r.reportPeriod rp WHERE rp.id = :reportPeriodId")
List<RatingItem> getRating(@Param("reportPeriodId") Integer reportPeriodId);
}

View File

@ -0,0 +1,35 @@
package ru.ulstu.report.service;
import org.springframework.stereotype.Service;
import ru.ulstu.aspirant.model.Aspirant;
import ru.ulstu.aspirant.service.AspirantService;
import ru.ulstu.report.model.Report;
import ru.ulstu.report.model.ReportPeriod;
import ru.ulstu.report.repository.ReportRepository;
import ru.ulstu.user.UserService;
import java.util.List;
@Service
public class ReportService {
private final ReportRepository reportRepository;
private final UserService userService;
private final AspirantService aspirantService;
public ReportService(ReportRepository reportRepository,
UserService userService,
AspirantService aspirantService) {
this.reportRepository = reportRepository;
this.userService = userService;
this.aspirantService = aspirantService;
}
public List<Report> getReports(ReportPeriod reportPeriod) {
return reportRepository.findAllByReportPeriod(reportPeriod);
}
public boolean canCreateReport(ReportPeriod reportPeriod) {
Aspirant currentAspirant = aspirantService.getAspirantByUser(userService.getCurrentUser());
return reportRepository.findByReportPeriodAndAspirant(reportPeriod, currentAspirant) == null;
}
}

View File

@ -94,4 +94,8 @@ public class UserService implements UserDetailsService {
public void initDefaultHead() {
createDefaultUser("head", UserRoleConstants.HEAD);
}
public User getCurrentUser() {
return getUserByLogin(UserUtils.getCurrentUserLogin());
}
}

View File

@ -37,7 +37,7 @@
aria-haspopup="true" aria-expanded="false">Аспиранту</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/aspirant/aspirantReport">Новый отчет аспиранта по БРС</a>
<a class="dropdown-item" href="/aspirant/listAspirantReports">Список отчетов</a>
<a class="dropdown-item" href="/report/reportList">Список отчетов</a>
</div>
</li>
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_MANAGER')">
@ -45,7 +45,7 @@
aria-haspopup="true" aria-expanded="false">Руководителю</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/aspirantList">Список аспирантов</a>
<a class="dropdown-item" href="/listAspirantReports">Список отчетов</a>
<a class="dropdown-item" href="/report/reportList">Список отчетов</a>
</div>
</li>
<li class="nav-item dropdown" sec:authorize="hasRole('ROLE_HEAD')">
@ -53,7 +53,7 @@
aria-haspopup="true" aria-expanded="false">Аспирантура</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/admin/reportPeriodList">Список периодов отчетности</a>
<a class="dropdown-item" href="/listAspirantReports">Список отчетов</a>
<a class="dropdown-item" href="/report/reportList">Список отчетов</a>
<a class="dropdown-item" href="/statistic/statistic">Статистика по баллам</a>
</div>
</li>
@ -65,9 +65,9 @@
<a class="dropdown-item" href="/admin/managers">Список научных руководителей</a>
<a class="dropdown-item" href="/admin/aspirants">Список аспирантов</a>
<a class="dropdown-item" href="/admin/reportPeriodList">Список периодов отчетности</a>
<a class="dropdown-item" href="/admin/reports">Отчетность аспирантов</a>
<a class="dropdown-item" href="/admin/rules">Правила БРС</a>
<a class="dropdown-item" href="/admin/confirmation">Подтверждение БРС</a>
<a class="dropdown-item" href="/report/reportList">Список отчетов</a>
<a class="dropdown-item" href="/statistic/statistic">Статистика по баллам</a>
<a class="dropdown-item" href="/admin">Новости и заседания</a>
</div>

View File

@ -0,0 +1,62 @@
<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:th="http://www.w3.org/1999/xhtml"
layout:decorate="~{default}">
<div class="container" layout:fragment="content">
<form action="/report/reportList" method="post" th:object="${reportListForm}">
<div class="row">
<div class="col col-md-2">
<div class="form-group">
<label for="period">Период отчетности</label>
</div>
</div>
<div class="col col-md-4">
<div class="form-group">
<select class="form-select form-control"
id="period" aria-label="multiple select example"
th:field="*{reportPeriod}">
<option th:each="p : ${reportPeriods}"
th:value="${p.id}"
th:text="${#calendars.format(p.startDate, 'dd.MM.yyyy') + ' - ' + #calendars.format(p.endDate, 'dd.MM.yyyy')}">
</option>
</select>
</div>
</div>
<div class="col col-md-4">
<div class="form-group">
<button type="submit" class="btn btn-outline-dark">Применить</button>
</div>
</div>
</div>
</form>
<a href="/report/editReport/0" class="btn btn-outline-dark" th:if="${canCreate}">
<i class="fa fa-plus-square" aria-hidden="true"> Добавить отчет</i>
</a>
<!-- Таблица аспирантов -->
<table class="table table-bordered table-striped mt-3">
<thead class="table-dark">
<tr>
<th scope="col">Период отчета</th>
<th scope="col">Аспирант</th>
<th scope="col">Дата создания</th>
<th scope="col">Статус</th>
</tr>
</thead>
<tbody>
<tr th:each="r : ${reports}">
<td th:text="${#calendars.format(r.reportPeriod.startDate, 'dd.MM.yyyy') + ' - ' + #calendars.format(r.reportPeriod.endDate, 'dd.MM.yyyy')}"></td>
<td th:text="${r.aspirant.surname + ' '+ r.aspirant.name + ' '+ r.aspirant.patronymic }"></td>
<td th:text="${#calendars.format(r.createDate, 'dd.MM.yyyy HH:mm')}"></td>
<td th:text="${r.status}"></td>
<td>
<!-- Ссылка на редактирование -->
<a th:href="@{'/report/editReport/' + ${r.id}}" class="btn btn-sm btn-primary">
<i class="fa fa-edit" aria-hidden="true"></i> Редактировать
</a>
</td>
</tr>
</tbody>
</table>
</div>
</html>