From 27ff4a3f4e820a6628bc833fec69bc92a08755b8 Mon Sep 17 00:00:00 2001 From: Anton Romanov Date: Mon, 14 Mar 2022 12:18:38 +0400 Subject: [PATCH] #7 -- add mvc for meetings --- data/db.mv.db | Bin 61440 -> 49152 bytes .../configuration/SecurityConfiguration.java | 2 +- .../ru/ulstu/controller/NewsController.java | 2 + src/main/java/ru/ulstu/meeting/Meeting.java | 55 +++++++++++ .../ru/ulstu/meeting/MeetingController.java | 88 ++++++++++++++++++ .../ru/ulstu/meeting/MeetingRepository.java | 9 ++ .../java/ru/ulstu/meeting/MeetingService.java | 47 ++++++++++ src/main/resources/templates/admin.html | 3 + src/main/resources/templates/default.html | 4 +- src/main/resources/templates/editMeeting.html | 33 +++++++ src/main/resources/templates/meetings.html | 40 ++++++++ src/main/resources/templates/viewMeeting.html | 23 +++++ 12 files changed, 303 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ru/ulstu/meeting/Meeting.java create mode 100644 src/main/java/ru/ulstu/meeting/MeetingController.java create mode 100644 src/main/java/ru/ulstu/meeting/MeetingRepository.java create mode 100644 src/main/java/ru/ulstu/meeting/MeetingService.java create mode 100644 src/main/resources/templates/editMeeting.html create mode 100644 src/main/resources/templates/meetings.html create mode 100644 src/main/resources/templates/viewMeeting.html diff --git a/data/db.mv.db b/data/db.mv.db index 49a6a54388a3b0c978a5bd5d7c4a5f5f1c7f537f..1c534f284e2845a2346862a6ae7b9e030cd401ca 100644 GIT binary patch literal 49152 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 literal 61440 zcmeG_ZEPIJbw`RPOOz;yvMpJ%q^!@DEhXpk?%sZ~3G5^9PCSVp5|5;%v}?< zBX!?=?am$Vj+8{jQarN3y_wyadGp?zH}l@SnKwS7#tWs2`<@YtJoEmqc_WG}%W?O7 zqx_x`*E8a7)pP1zaYQi}4aag8J;RPKR;tTReME_0@TxVxQpO)Hmb|)q-m8u{wxM}W zQ6G$me*yyn0|EmA0|EmA0|EmA0|EmA0|EmA0|EmA18+D6#)ba>hSNX*ATS^>ATS^> zATS^>ATS^>ATS^>ATS^>ATV&XF+ex@i;L6?K#iBY@<=ki?5vD97CasrNouwnFMAKw zM~d+kXUVI9dqBKesnkc3Nz(;S0oih0Eg7%-%iuX+>89Z-PUsc@Rj>Hvu}Y&{ACaZa z{Ri#^d)|BKz?LHsMNMkDVMez_w?_w~JEA+IL(yH)-O)YK;ppDzjnSK;H%IqH_eXDu z9*7={-Woj=Jsdp}86LPzy7O#4Gb@eFWKy%4h0(d(L|Rg1d3Ycu#fIMBNAjh)d}c<< zWu>X;0(p|QuS%#}yo}${ep%m_t##8xm=`PcBRnIaNWl^_P zMbR`(Ng9QsS11%st57stSt&ZQ;>eDxIcCArRK2KKnq?Qvq-PZ5yQEZlGB-6maJwW8 zU7(ZXnFtmR;A8ErO1Y_Y<}6pVwI9O+cLLg9W-QPJ?^Buk14QT2F{pDka{@YnIE6#( zd}bz}o1O~ZQ+%g^U@>VnH<`)LrY29*+*zPPOd6Y*9%UK1*@-sF(KkSj6FuH6WOEal z4s=I!y$k4?*)UyGY8zom$79fEsOuPzuilw@_`3~}3tDI)7pl4^jR24kg{=i;t%+5{aV7gpGvAI(VhN4cMNS{h(%sE-R-?XfhBB#e?E4hH@jfEcFB$x+o z8@LgA`tja_wpUksff17k?8joXxy$PW0C^MO<2)sA`<$3PH7-x(#!qUxmOYz$r%sy`4;ztbErM*|Wh5E(2UsyFJ3W)hotQ$alw)fI=^8Bcs4DE? zOeUL|!K*4x{RLzGr(URJG6I%Q42QRXto&mC#%7m%CXZHG zS0FRTr}MD%>a|49onC;o=M1#e`#U@+7tqpbx!LxwsC1^iSwND%7es98 z2F`9>d!qHpzyaXFGaHuO>1=1=4O#_5EfeAgf#)7shv$M)-A6LFUPp~znmC6N(8XJ! ziz~E?-Q~GGGdG)`Gjg_)PV3|MpHa;da(-T$p9opA<8TZ5fD{Of1Vj;p+CzYW&s{kN zK*)E6Efn&6+iPT4uPTD>0mO#^Q(kw0q}+d2IhoP(Q)gz5uiu96u|^`nG=UUIWQ1mwuW8X21+5*F3V?-yB(utnPrP)zqcczNX%MJN$e{Q(lcU

mo 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 T4)_06!-SEehPvJ6{2Kg!v-~pM diff --git a/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java b/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java index f893257..f479e11 100644 --- a/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java +++ b/src/main/java/ru/ulstu/configuration/SecurityConfiguration.java @@ -45,7 +45,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { log.debug("Security enabled"); http.authorizeRequests() .antMatchers("/").permitAll() - .antMatchers("/login", "/index", "/news/**", "/h2-console/*", "/h2-console").permitAll() + .antMatchers("/login", "/index", "/news/**", "/meetings/**", "/h2-console/*", "/h2-console").permitAll() .antMatchers("/swagger-ui.html").hasAuthority(UserRoleConstants.ADMIN) .anyRequest().authenticated() .and() diff --git a/src/main/java/ru/ulstu/controller/NewsController.java b/src/main/java/ru/ulstu/controller/NewsController.java index a2f2859..139daa5 100644 --- a/src/main/java/ru/ulstu/controller/NewsController.java +++ b/src/main/java/ru/ulstu/controller/NewsController.java @@ -59,6 +59,7 @@ public class NewsController { } @GetMapping("/editNews/{newsId}") + @Secured({UserRoleConstants.ADMIN}) public String editNews(@PathVariable(value = "newsId") Integer id, Model model) { model.addAttribute("news", (id != null && id != 0) ? newsService.getById(id) : new News()); return "editNews"; @@ -82,6 +83,7 @@ public class NewsController { } @GetMapping("deleteNews/{newsId}") + @Secured({UserRoleConstants.ADMIN}) public String delete(@PathVariable(value = "newsId") Integer id) { newsService.delete(id); return "redirect:/news/news"; diff --git a/src/main/java/ru/ulstu/meeting/Meeting.java b/src/main/java/ru/ulstu/meeting/Meeting.java new file mode 100644 index 0000000..fcc9266 --- /dev/null +++ b/src/main/java/ru/ulstu/meeting/Meeting.java @@ -0,0 +1,55 @@ +package ru.ulstu.meeting; + +import org.springframework.format.annotation.DateTimeFormat; +import ru.ulstu.model.BaseEntity; + +import javax.persistence.Entity; +import javax.persistence.Lob; +import javax.validation.constraints.NotEmpty; +import java.util.Date; + +@Entity +public class Meeting extends BaseEntity { + @NotEmpty(message = "Заголовок не может быть пустым") + private String title; + + @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") + private Date date; + + @Lob + @NotEmpty(message = "Текст заседания не может быть пустым") + private String text; + + public Meeting() { + } + + public Meeting(String title, String text, Date date) { + this.title = title; + this.date = date; + this.text = text; + } + + public String getTitle() { + return title; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setText(String text) { + this.text = text; + } + + public String getText() { + return text; + } +} diff --git a/src/main/java/ru/ulstu/meeting/MeetingController.java b/src/main/java/ru/ulstu/meeting/MeetingController.java new file mode 100644 index 0000000..f85eea3 --- /dev/null +++ b/src/main/java/ru/ulstu/meeting/MeetingController.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2021 Anton Romanov - All Rights Reserved + * You may use, distribute and modify this code, please write to: romanov73@gmail.com. + * + */ + +package ru.ulstu.meeting; + +import org.springframework.data.domain.Page; +import org.springframework.security.access.annotation.Secured; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import ru.ulstu.model.OffsetablePageRequest; +import ru.ulstu.model.UserRoleConstants; + +import javax.validation.Valid; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@Controller +@RequestMapping("meetings") +public class MeetingController { + private final static int DEFAULT_PAGE_SIZE = 10; + private final MeetingService meetingService; + + public MeetingController(MeetingService meetingService) { + this.meetingService = meetingService; + } + + @GetMapping("/meetings") + public String listMeetings(Model model, + @RequestParam Optional page, + @RequestParam Optional size) { + int currentPage = page.orElse(1); + int pageSize = size.orElse(DEFAULT_PAGE_SIZE); + + Page meetingsPage = meetingService.getMeetings(new OffsetablePageRequest(currentPage - 1, pageSize)); + model.addAttribute("meetings", meetingsPage); + int totalPages = meetingsPage.getTotalPages(); + if (totalPages > 0) { + List pageNumbers = IntStream.rangeClosed(1, totalPages) + .boxed() + .collect(Collectors.toList()); + model.addAttribute("pageNumbers", pageNumbers); + } + return "meetings"; + } + + @GetMapping("/editMeeting/{meetingId}") + @Secured({UserRoleConstants.ADMIN}) + public String editMeeting(@PathVariable(value = "meetingId") Integer id, Model model) { + model.addAttribute("meeting", (id != null && id != 0) ? meetingService.getById(id) : new Meeting()); + return "editMeeting"; + } + + @GetMapping("/meetings/{meetingId}") + public String viewMeeting(@PathVariable(value = "meetingId") Integer id, Model model) { + model.addAttribute("meeting", id != null ? meetingService.getById(id) : new Meeting()); + return "viewMeeting"; + } + + @PostMapping("saveMeeting") + @Secured({UserRoleConstants.ADMIN}) + public String saveNews(@Valid @ModelAttribute Meeting meeting, + BindingResult result) { + if (result.hasErrors()) { + return "editMeeting"; + } + meetingService.save(meeting); + return "redirect:/meetings/meetings"; + } + + @GetMapping("deleteMeeting/{meetingId}") + @Secured({UserRoleConstants.ADMIN}) + public String delete(@PathVariable(value = "meetingId") Integer id) { + meetingService.delete(id); + return "redirect:/meetings/meetings"; + } +} diff --git a/src/main/java/ru/ulstu/meeting/MeetingRepository.java b/src/main/java/ru/ulstu/meeting/MeetingRepository.java new file mode 100644 index 0000000..e3e964d --- /dev/null +++ b/src/main/java/ru/ulstu/meeting/MeetingRepository.java @@ -0,0 +1,9 @@ +package ru.ulstu.meeting; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; + +interface MeetingRepository extends JpaRepository { + Page findByOrderByDateDesc(Pageable pageable); +} diff --git a/src/main/java/ru/ulstu/meeting/MeetingService.java b/src/main/java/ru/ulstu/meeting/MeetingService.java new file mode 100644 index 0000000..fb92aef --- /dev/null +++ b/src/main/java/ru/ulstu/meeting/MeetingService.java @@ -0,0 +1,47 @@ +package ru.ulstu.meeting; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import ru.ulstu.service.NewsService; + +import javax.validation.constraints.NotNull; + +@Service +public class MeetingService { + private final MeetingRepository meetingRepository; + private final NewsService newsService; + + public MeetingService(MeetingRepository meetingRepository, + NewsService newsService) { + this.meetingRepository = meetingRepository; + this.newsService = newsService; + } + + public void create(Meeting meeting) { + meetingRepository.save(meeting); + newsService.create("Очередное заседание семинара", "Заседание семинара состоится " + meeting.getDate()); + } + + public void save(Meeting meeting) { + if (meeting.getId() != null && (meeting.getId() != 0)) { + meetingRepository.save(meeting); + } else { + create(meeting); + } + } + + public Meeting getById(@NotNull Integer id) { + return meetingRepository + .findById(id) + .orElseThrow(() -> new RuntimeException("Запись о заседании не найдена")); + } + + public void delete(Integer id) { + meetingRepository.deleteById(id); + } + + public Page getMeetings(Pageable pageable) { + return meetingRepository.findByOrderByDateDesc(pageable); + } +} diff --git a/src/main/resources/templates/admin.html b/src/main/resources/templates/admin.html index 22e05cf..a76d673 100644 --- a/src/main/resources/templates/admin.html +++ b/src/main/resources/templates/admin.html @@ -10,5 +10,8 @@ + + + diff --git a/src/main/resources/templates/default.html b/src/main/resources/templates/default.html index 99f7ed0..505c93c 100644 --- a/src/main/resources/templates/default.html +++ b/src/main/resources/templates/default.html @@ -36,10 +36,10 @@ Новости