LabWork04-05 / Add additions

This commit is contained in:
parent c4d148f611
commit 3587ec2acf
7 changed files with 53 additions and 17 deletions

Binary file not shown.

View File

@ -84,21 +84,21 @@ public class DemoApplication implements CommandLineRunner {
log.info("Create default messages values");
final var messages1 = List.of(
new MessageEntity("Message1", LocalDateTime.now(), false),
new MessageEntity("Message1", LocalDateTime.now(), true),
new MessageEntity("Message2", LocalDateTime.now(), false),
new MessageEntity("Message3", LocalDateTime.now(), false)
new MessageEntity("Message3", LocalDateTime.now(), true)
);
messages1.forEach(message -> messageService.create(user1.getId(), message));
final var messages2 = List.of(
new MessageEntity("Message4", LocalDateTime.now(), false),
new MessageEntity("Message5", LocalDateTime.now(), false)
new MessageEntity("Message5", LocalDateTime.now(), true)
);
messages2.forEach(message -> messageService.create(user2.getId(), message));
final var messages3 = List.of(
new MessageEntity("Message6", LocalDateTime.now(), false),
new MessageEntity("Message7", LocalDateTime.now(), false)
new MessageEntity("Message7", LocalDateTime.now(), true)
);
messages3.forEach(message -> messageService.create(user3.getId(), message));
}

View File

@ -3,6 +3,7 @@ package com.example.demo.messages.api;
import java.util.Map;
import org.modelmapper.ModelMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@ -22,7 +23,7 @@ import com.example.demo.messages.service.MessageService;
@RequestMapping(MessageController.URL)
public class MessageController {
// URL для доступа к методам контроллера
public static final String URL = Constants.ADMIN_PREFIX + "/message";
public static final String URL = "/message";
// Представление для отображения списка сообщений
private static final String MESSAGE_VIEW = "messages";
@ -48,6 +49,7 @@ public class MessageController {
}
// Получить все элементы
@PreAuthorize("hasRole('ADMIN')")
@GetMapping
public String getAll(
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
@ -60,7 +62,21 @@ public class MessageController {
return MESSAGE_VIEW;
}
// Получить опубликованные сообщения с пагинацией
@GetMapping("/published")
public String getPublishedMessages(
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
Model model) {
final Map<String, Object> attributes = PageAttributesMapper.toAttributes(
"message",
messageService.getPublishedMessages(page, Constants.DEFAULT_PAGE_SIZE), this::toDto);
model.addAllAttributes(attributes);
model.addAttribute(PAGE_ATTRIBUTE, page);
return MESSAGE_VIEW;
}
// Удалить элемент
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/delete/{id}")
public String delete(
@PathVariable(name = "id") Long id,
@ -73,6 +89,7 @@ public class MessageController {
}
// Опубликовать сообщение
@PreAuthorize("hasRole('ADMIN')")
@PostMapping("/publish/{id}")
public String publish(
@PathVariable(name = "id") Long id,

View File

@ -5,15 +5,21 @@ import java.util.Optional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import com.example.demo.messages.model.MessageEntity;
// Хранилище для сущности "Сообщение"
public interface MessageRepository extends CrudRepository<MessageEntity, Long>, PagingAndSortingRepository<MessageEntity, Long> {
// Получить сообщение по пользователю и идентификатору
Optional<MessageEntity> findOnyByUserIdAndId(Long userId, Long id);
Optional<MessageEntity> findOneByUserIdAndId(Long userId, Long id);
// Получить сообщение по идентификатору с предварительной загрузкой связанных сущностей
@Query("SELECT m FROM MessageEntity m JOIN FETCH m.user u LEFT JOIN FETCH u.messages WHERE m.id = :id")
Optional<MessageEntity> findByIdWithUser(@Param("id") Long id);
// Получить список всех сообщений (с пагинацией)
Page<MessageEntity> findAll(Pageable pageable);
@ -23,4 +29,7 @@ public interface MessageRepository extends CrudRepository<MessageEntity, Long>,
// Получить список сообщений по пользователю (с пагинацией)
Page<MessageEntity> findByUserId(Long userId, Pageable pageable);
// Получить все опубликованные сообщения (с пагинацией)
Page<MessageEntity> findByIsPublishedTrue(Pageable pageable);
}

View File

@ -55,20 +55,26 @@ public class MessageService {
}
}
// Получить страницу опубликованных сообщений
@Transactional(readOnly = true)
public Page<MessageEntity> getPublishedMessages(int page, int size) {
final PageRequest pageRequest = PageRequest.of(page, size);
return repository.findByIsPublishedTrue(pageRequest);
}
// Получить элемент по идентификатору
@Transactional(readOnly = true)
public MessageEntity get(Long userId, Long id) {
userService.get(userId);
return repository.findOnyByUserIdAndId(userId, id)
return repository.findOneByUserIdAndId(userId, id)
.orElseThrow(() -> new NotFoundException(MessageEntity.class, id));
}
// Получить элемент по идентификатору
@Transactional(readOnly = true)
public MessageEntity get(Long id) {
MessageEntity message = repository.findById(id)
MessageEntity message = repository.findByIdWithUser(id)
.orElseThrow(() -> new NotFoundException(MessageEntity.class, id));
Hibernate.initialize(message.getUser().getMessages());
return message;
}

View File

@ -42,12 +42,16 @@
th:classappend="${activeLink.startsWith('/admin/type') ? 'active' : ''}">
Types
</a>
<a class="nav-link" href="/admin/message"
th:classappend="${activeLink.startsWith('/admin/message') ? 'active' : ''}">
<a class="nav-link" href="/message"
th:classappend="${activeLink.startsWith('/message') ? 'active' : ''}">
Messages
</a>
<a class="nav-link" href="/h2-console/" target="_blank">Console H2</a>
</th:block>
<a class="nav-link" href="/message/published"
th:classappend="${activeLink.startsWith('/message/published') ? 'active' : ''}">
Published messages
</a>
</ul>
<ul class="navbar d-flex align-center" th:if="${not #strings.isEmpty(userName)}">
<form th:action="@{/logout}" method="post">

View File

@ -20,8 +20,8 @@
<th scope="col" class="w-auto">Message</th>
<th scope="col" class="w-10">Date</th>
<th scope="col" class="w-4" style="text-align: center;">Published</th>
<th scope="col" class="w-10"></th>
<th scope="col" class="w-10"></th>
<th sec:authorize="hasRole('ADMIN')" scope="col" class="w-10"></th>
<th sec:authorize="hasRole('ADMIN')" scope="col" class="w-10"></th>
</tr>
</thead>
<tbody>
@ -33,15 +33,15 @@
<td style="text-align: center;">
<input type="checkbox" th:checked="${message.isPublished}" style="display: inline-block;" disabled/>
</td>
<td>
<form th:action="@{/admin/message/publish/{id}(id=${message.id})}" method="post">
<td sec:authorize="hasRole('ADMIN')">
<form th:action="@{/message/publish/{id}(id=${message.id})}" method="post">
<input type="hidden" th:name="page" th:value="${page}">
<button type="submit" class="btn"
onclick="return confirm('Are you sure?')">Publish</button>
</form>
</td>
<td>
<form th:action="@{/admin/message/delete/{id}(id=${message.id})}" method="post">
<td sec:authorize="hasRole('ADMIN')">
<form th:action="@{/message/delete/{id}(id=${message.id})}" method="post">
<input type="hidden" th:name="page" th:value="${page}">
<button type="submit" class="btn"
onclick="return confirm('Are you sure?')">Delete</button>