Compare commits

...

6 Commits

Author SHA1 Message Date
a503a36e8b Divide admin controllers and services 2025-01-29 14:14:48 +04:00
3b877050b7 Add aspirant edit templates 2025-01-29 14:14:22 +04:00
232dc68db4 Add aspirant edit templates 2025-01-29 14:14:06 +04:00
da65669c90 Add aspirant model 2025-01-29 14:13:47 +04:00
6ad4ea0083 Add aspirant model 2025-01-29 14:13:34 +04:00
10f65e11a2 Fix menu 2025-01-29 13:06:01 +04:00
18 changed files with 528 additions and 13 deletions

View File

@ -0,0 +1,50 @@
package ru.ulstu.admin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.admin.model.AspirantForm;
import ru.ulstu.admin.service.AdminAspirantService;
import ru.ulstu.indicator.model.Course;
import ru.ulstu.indicator.model.Indicator;
@Controller
@RequestMapping("admin")
public class AdminAspirantController {
private final AdminAspirantService adminAspirantService;
public AdminAspirantController(AdminAspirantService adminAspirantService) {
this.adminAspirantService = adminAspirantService;
}
@GetMapping("aspirants")
public String getListOfAspirants(Model model) {
model.addAttribute("aspirants", adminAspirantService.getAspirants());
return "admin/aspirantsList";
}
@GetMapping("/editAspirant/{aspirantId}")
public String editAspirant(@PathVariable(value = "aspirantId") Integer id, Model model) {
model.addAttribute("aspirant",
(id != null && id != 0)
? adminAspirantService.getAspirantById(id)
: new Indicator());
model.addAttribute("courses", Course.values());
return "admin/editAspirant";
}
@PostMapping(value = "saveAspirant", params = "save")
public String saveAspirant(AspirantForm aspirantForm, Model model) {
adminAspirantService.saveAspirant(aspirantForm);
return "redirect:/admin/aspirants";
}
@PostMapping(value = "saveAspirant", params = "delete")
public String deleteIndicator(AspirantForm aspirantForm, Model model) {
adminAspirantService.deleteAspirant(aspirantForm);
return "redirect:/admin/aspirants";
}
}

View File

@ -1,4 +1,4 @@
package ru.ulstu.admin.service; package ru.ulstu.admin.controller;
import org.springframework.security.access.annotation.Secured; import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -8,6 +8,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import ru.ulstu.admin.model.IndicatorForm; import ru.ulstu.admin.model.IndicatorForm;
import ru.ulstu.admin.service.AdminIndicatorService;
import ru.ulstu.indicator.model.Course; import ru.ulstu.indicator.model.Course;
import ru.ulstu.indicator.model.Indicator; import ru.ulstu.indicator.model.Indicator;
import ru.ulstu.model.UserRoleConstants; import ru.ulstu.model.UserRoleConstants;
@ -15,17 +16,17 @@ import ru.ulstu.model.UserRoleConstants;
@Controller @Controller
@RequestMapping("/admin") @RequestMapping("/admin")
@Secured({UserRoleConstants.ADMIN}) @Secured({UserRoleConstants.ADMIN})
public class AdminController { public class AdminIndicatorController {
private final AdminService adminService; private final AdminIndicatorService adminIndicatorService;
public AdminController(AdminService adminService) { public AdminIndicatorController(AdminIndicatorService adminIndicatorService) {
this.adminService = adminService; this.adminIndicatorService = adminIndicatorService;
} }
@GetMapping("indicators") @GetMapping("indicators")
public String getListOfIndicators(Model model) { public String getListOfIndicators(Model model) {
model.addAttribute("indicators", adminService.getIndicators()); model.addAttribute("indicators", adminIndicatorService.getIndicators());
return "indicatorsList"; return "admin/indicatorsList";
} }
@GetMapping("/editIndicator/{indicatorId}") @GetMapping("/editIndicator/{indicatorId}")
@ -33,21 +34,21 @@ public class AdminController {
public String editIndicator(@PathVariable(value = "indicatorId") Integer id, Model model) { public String editIndicator(@PathVariable(value = "indicatorId") Integer id, Model model) {
model.addAttribute("indicator", model.addAttribute("indicator",
(id != null && id != 0) (id != null && id != 0)
? adminService.getIndicatorById(id) ? adminIndicatorService.getIndicatorById(id)
: new Indicator()); : new Indicator());
model.addAttribute("courses", Course.values()); model.addAttribute("courses", Course.values());
return "editIndicator"; return "admin/editIndicator";
} }
@PostMapping(value = "saveIndicator", params = "save") @PostMapping(value = "saveIndicator", params = "save")
public String saveIndicator(IndicatorForm indicatorForm, Model model) { public String saveIndicator(IndicatorForm indicatorForm, Model model) {
adminService.saveIndicator(indicatorForm); adminIndicatorService.saveIndicator(indicatorForm);
return "redirect:/admin/indicators"; return "redirect:/admin/indicators";
} }
@PostMapping(value = "saveIndicator", params = "delete") @PostMapping(value = "saveIndicator", params = "delete")
public String deleteIndicator(IndicatorForm indicatorForm, Model model) { public String deleteIndicator(IndicatorForm indicatorForm, Model model) {
adminService.deleteIndicator(indicatorForm); adminIndicatorService.deleteIndicator(indicatorForm);
return "redirect:/admin/indicators"; return "redirect:/admin/indicators";
} }
} }

View File

@ -0,0 +1,110 @@
package ru.ulstu.admin.model;
import ru.ulstu.aspirant.model.Base;
import ru.ulstu.aspirant.model.Speciality;
import ru.ulstu.indicator.model.Course;
import ru.ulstu.manager.model.Manager;
import java.util.Date;
public class AspirantForm {
private Integer id;
private String surname;
private String name;
private String patronymic;
private Course course;
private Manager manager;
private Date birthDate;
private Speciality speciality;
private String theme;
private Base base;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Speciality getSpeciality() {
return speciality;
}
public void setSpeciality(Speciality speciality) {
this.speciality = speciality;
}
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public Base getBase() {
return base;
}
public void setBase(Base base) {
this.base = base;
}
}

View File

@ -0,0 +1,45 @@
package ru.ulstu.admin.service;
import org.springframework.stereotype.Service;
import ru.ulstu.admin.model.AspirantForm;
import ru.ulstu.aspirant.model.Aspirant;
import ru.ulstu.aspirant.service.AspirantService;
import java.util.List;
@Service
public class AdminAspirantService {
private final AspirantService aspirantService;
public AdminAspirantService(AspirantService aspirantService) {
this.aspirantService = aspirantService;
}
public List<Aspirant> getAspirants() {
return aspirantService.getAspirants();
}
public Aspirant getAspirantById(Integer id) {
return aspirantService.getAspirantById(id);
}
public void saveAspirant(AspirantForm aspirantForm) {
Aspirant aspirant = aspirantForm.getId() == null
? new Aspirant(aspirantForm)
: aspirantService.getAspirantById(aspirantForm.getId());
aspirant.setName(aspirantForm.getName());
aspirant.setSurname(aspirantForm.getSurname());
aspirant.setPatronymic(aspirantForm.getPatronymic());
aspirant.setBase(aspirantForm.getBase());
aspirant.setCourse(aspirantForm.getCourse());
aspirant.setManager(aspirantForm.getManager());
aspirant.setBirthDate(aspirantForm.getBirthDate());
aspirant.setSpeciality(aspirantForm.getSpeciality());
aspirant.setTheme(aspirantForm.getTheme());
aspirantService.save(aspirant);
}
public void deleteAspirant(AspirantForm aspirantForm) {
aspirantService.deleteAspirant(aspirantForm);
}
}

View File

@ -8,10 +8,10 @@ import ru.ulstu.indicator.service.IndicatorService;
import java.util.List; import java.util.List;
@Service @Service
public class AdminService { public class AdminIndicatorService {
private final IndicatorService indicatorService; private final IndicatorService indicatorService;
public AdminService(IndicatorService indicatorService) { public AdminIndicatorService(IndicatorService indicatorService) {
this.indicatorService = indicatorService; this.indicatorService = indicatorService;
} }

View File

@ -0,0 +1,121 @@
package ru.ulstu.aspirant.model;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import ru.ulstu.admin.model.AspirantForm;
import ru.ulstu.indicator.model.Course;
import ru.ulstu.manager.model.Manager;
import ru.ulstu.model.BaseEntity;
import java.util.Date;
@Entity
public class Aspirant extends BaseEntity {
@NotEmpty
private String surname;
@NotEmpty
private String name;
private String patronymic;
@NotNull
private Course course;
@ManyToOne
private Manager manager;
@Temporal(TemporalType.DATE)
private Date birthDate;
@Enumerated(EnumType.STRING)
private Speciality speciality;
private String theme;
@Enumerated(EnumType.STRING)
private Base base;
public Aspirant(AspirantForm aspirantForm) {
this.name = aspirantForm.getName();
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
public Manager getManager() {
return manager;
}
public void setManager(Manager manager) {
this.manager = manager;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Speciality getSpeciality() {
return speciality;
}
public void setSpeciality(Speciality speciality) {
this.speciality = speciality;
}
public String getTheme() {
return theme;
}
public void setTheme(String theme) {
this.theme = theme;
}
public Base getBase() {
return base;
}
public void setBase(Base base) {
this.base = base;
}
}

View File

@ -0,0 +1,15 @@
package ru.ulstu.aspirant.model;
public enum Base {
BUDGET("бюджет"), COMMERCE("коммерческая");
private final String name;
Base(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,22 @@
package ru.ulstu.aspirant.model;
public enum Speciality {
S_2_3_7("2.3.7", "Системный анализ"),
S_2_3_1("2.3.1", "Автоматизация проектирования");
private final String code;
private final String name;
Speciality(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
}

View File

@ -0,0 +1,7 @@
package ru.ulstu.aspirant.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.ulstu.aspirant.model.Aspirant;
public interface AspirantRepository extends JpaRepository<Aspirant, Integer> {
}

View File

@ -0,0 +1,33 @@
package ru.ulstu.aspirant.service;
import org.springframework.stereotype.Service;
import ru.ulstu.admin.model.AspirantForm;
import ru.ulstu.aspirant.model.Aspirant;
import ru.ulstu.aspirant.repository.AspirantRepository;
import java.util.List;
@Service
public class AspirantService {
private final AspirantRepository aspirantRepository;
public AspirantService(AspirantRepository aspirantRepository) {
this.aspirantRepository = aspirantRepository;
}
public List<Aspirant> getAspirants() {
return aspirantRepository.findAll();
}
public Aspirant getAspirantById(Integer id) {
return aspirantRepository.findById(id).orElseThrow(() -> new RuntimeException("Aspirant not found by id"));
}
public void save(Aspirant aspirant) {
aspirantRepository.save(aspirant);
}
public void deleteAspirant(AspirantForm aspirantForm) {
aspirantRepository.deleteById(aspirantForm.getId());
}
}

View File

@ -0,0 +1,17 @@
package ru.ulstu.manager.model;
import jakarta.persistence.Entity;
import ru.ulstu.model.BaseEntity;
@Entity
public class Manager extends BaseEntity {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,17 @@
<!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">
<a href="/admin/editAspirant/0" class="btn btn-outline-dark">
<i class="fa fa-plus-square" aria-hidden="true"> Добавить аспиранта</i>
</a>
<ul>
<li th:each="a : ${aspirants}">
<a th:href="@{'/admin/editAspirant/' + ${a.id}}">
<span th:text="{${a.surname} + ' '+ ${a.name} + ' ' + ${a.patronymic}}"></span>
</a>
</li>
</ul>
</div>
</html>

View File

@ -0,0 +1,76 @@
<!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">
<h3>Редактирование показателя:</h3>
<form action="#" th:action="@{/admin/saveIndicator}"
th:object="${indicator}"
method="post"
enctype="multipart/form-data">
<input type="hidden" th:field="*{id}">
<div class="form-group">
<label for="name">Название</label>
<input th:field="*{name}"
id="name"
type="text"
required
class="form-control"
placeholder="Название показателя">
<p th:if="${#fields.hasErrors('name')}"
th:class="${#fields.hasErrors('name')}? error">
Не может быть пустым
</p>
</div>
<div class="form-group">
<label for="name">Максимальная сумма баллов</label>
<input th:field="*{max}"
required
id="max"
type="number"
class="form-control"
min="0"
max="30">
</div>
<div class="form-group">
<label for="name">Описание подтверждающих документов</label>
<textarea th:field="*{proofDocuments}"
required
id="proofDocuments"
class="form-control"
placeholder="Описание подтверждающих документов"
style="height: 100px">
</textarea>
<p th:if="${#fields.hasErrors('proofDocuments')}"
th:class="${#fields.hasErrors('proofDocuments')}? error">
Не может быть пустым
</p>
</div>
<div class="form-group">
<label for="courses">Для каких курсов применяется</label>
<select class="form-select form-control" id="courses" multiple aria-label="multiple select example"
th:field="*{courses}"
>
<option th:each="c : ${courses}"
th:value="${c}"
th:text="${c.name}">
</option>
</select>
</div>
<button name="save" type="submit" class="btn btn-outline-dark">Сохранить</button>
<button name="delete"
type="submit"
class="btn btn-outline-dark"
onclick="return confirm('Удалить показатель?')">
Удалить
</button>
<a href="/admin/indicators" class="btn btn-outline-dark">Отмена</a>
</form>
<link rel="stylesheet" href="/webjars/font-awesome/4.7.0/css/font-awesome.min.css"/>
<link rel="stylesheet" href="/webjars/bootstrap-glyphicons/bdd2cbfba0/css/bootstrap-glyphicons.css"/>
</div>
</html>

View File

@ -60,6 +60,7 @@
aria-haspopup="true" aria-expanded="false">Администратору</a> aria-haspopup="true" aria-expanded="false">Администратору</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown"> <div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="/admin/indicators">Список показателей</a> <a class="dropdown-item" href="/admin/indicators">Список показателей</a>
<a class="dropdown-item" href="/admin">Новости и заседания</a>
</div> </div>
</li> </li>
<li class="nav-item"> <li class="nav-item">