CollectionService.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. package com.izouma.nineth.service;
  2. import com.izouma.nineth.domain.*;
  3. import com.izouma.nineth.dto.CollectionDTO;
  4. import com.izouma.nineth.dto.CreateBlindBox;
  5. import com.izouma.nineth.dto.PageQuery;
  6. import com.izouma.nineth.dto.UserDTO;
  7. import com.izouma.nineth.enums.CollectionType;
  8. import com.izouma.nineth.exception.BusinessException;
  9. import com.izouma.nineth.repo.*;
  10. import com.izouma.nineth.utils.JpaUtils;
  11. import com.izouma.nineth.utils.SecurityUtils;
  12. import lombok.AllArgsConstructor;
  13. import org.apache.commons.collections.MapUtils;
  14. import org.springframework.beans.BeanUtils;
  15. import org.springframework.data.domain.Page;
  16. import org.springframework.data.domain.PageImpl;
  17. import org.springframework.data.jpa.domain.Specification;
  18. import org.springframework.scheduling.annotation.Scheduled;
  19. import org.springframework.stereotype.Service;
  20. import javax.persistence.criteria.CriteriaBuilder;
  21. import javax.persistence.criteria.CriteriaQuery;
  22. import javax.persistence.criteria.Predicate;
  23. import javax.persistence.criteria.Root;
  24. import javax.transaction.Transactional;
  25. import java.time.LocalDateTime;
  26. import java.util.ArrayList;
  27. import java.util.Arrays;
  28. import java.util.List;
  29. import java.util.stream.Collectors;
  30. @Service
  31. @AllArgsConstructor
  32. public class CollectionService {
  33. private CollectionRepo collectionRepo;
  34. private LikeRepo likeRepo;
  35. private BlindBoxItemRepo blindBoxItemRepo;
  36. private AppointmentRepo appointmentRepo;
  37. private UserRepo userRepo;
  38. public Page<Collection> all(PageQuery pageQuery) {
  39. pageQuery.getQuery().put("del", false);
  40. Specification<Collection> specification = JpaUtils.toSpecification(pageQuery, Collection.class);
  41. specification = specification.and((Specification<Collection>) (root, criteriaQuery, criteriaBuilder) -> {
  42. List<Predicate> and = new ArrayList<>();
  43. if (!MapUtils.getString(pageQuery.getQuery(), "type", "").equals("BLIND_BOX")) {
  44. and.add(criteriaBuilder.notEqual(root.get("type"), CollectionType.BLIND_BOX));
  45. }
  46. return criteriaBuilder.and(and.toArray(new Predicate[0]));
  47. });
  48. return collectionRepo.findAll(specification, JpaUtils.toPageRequest(pageQuery));
  49. }
  50. public Collection create(Collection record) {
  51. User minter = userRepo.findById(record.getMinterId()).orElse(SecurityUtils.getAuthenticatedUser());
  52. record.setMinter(minter.getNickname());
  53. record.setMinterId(minter.getId());
  54. record.setMinterAvatar(minter.getAvatar());
  55. record.setOwner(minter.getNickname());
  56. record.setOwnerId(minter.getId());
  57. record.setOwnerAvatar(minter.getAvatar());
  58. record.setStock(record.getTotal());
  59. record.setSale(0);
  60. if (record.isScheduleSale()) {
  61. if (record.getStartTime() == null) {
  62. throw new BusinessException("请填写定时发布时间");
  63. }
  64. record.setOnShelf(record.getStartTime().isBefore(LocalDateTime.now()));
  65. }
  66. return collectionRepo.save(record);
  67. }
  68. public CollectionDTO toDTO(Collection collection) {
  69. return toDTO(collection, true);
  70. }
  71. public CollectionDTO toDTO(Collection collection, boolean join) {
  72. CollectionDTO collectionDTO = new CollectionDTO();
  73. BeanUtils.copyProperties(collection, collectionDTO);
  74. if (join) {
  75. if (SecurityUtils.getAuthenticatedUser() != null) {
  76. List<Like> list = likeRepo.findByUserIdAndCollectionId(SecurityUtils.getAuthenticatedUser().getId(),
  77. collection.getId());
  78. collectionDTO.setLiked(!list.isEmpty());
  79. if (collection.getType() == CollectionType.BLIND_BOX) {
  80. collectionDTO.setAppointment(appointmentRepo.findFirstByBlindBoxId(collection.getId()).isPresent());
  81. }
  82. }
  83. }
  84. return collectionDTO;
  85. }
  86. public List<CollectionDTO> toDTO(List<Collection> collections) {
  87. List<Like> likes = new ArrayList<>();
  88. List<Appointment> appointments = new ArrayList<>();
  89. if (SecurityUtils.getAuthenticatedUser() != null) {
  90. likes.addAll(likeRepo.findByUserId(SecurityUtils.getAuthenticatedUser().getId()));
  91. appointments.addAll(appointmentRepo.findByUserId(SecurityUtils.getAuthenticatedUser().getId()));
  92. }
  93. return collections.stream().parallel().map(collection -> {
  94. CollectionDTO dto = toDTO(collection, false);
  95. if (!likes.isEmpty()) {
  96. dto.setLiked(likes.stream().anyMatch(l -> l.getCollectionId().equals(collection.getId())));
  97. }
  98. if (!appointments.isEmpty()) {
  99. dto.setAppointment(appointments.stream().anyMatch(a -> a.getBlindBoxId().equals(collection.getId())));
  100. }
  101. return dto;
  102. }).collect(Collectors.toList());
  103. }
  104. public Page<CollectionDTO> toDTO(Page<Collection> collections) {
  105. List<CollectionDTO> userDTOS = toDTO(collections.getContent());
  106. return new PageImpl<>(userDTOS, collections.getPageable(), collections.getTotalElements());
  107. }
  108. @Transactional
  109. public Collection createBlindBox(CreateBlindBox createBlindBox) {
  110. Collection blindBox = createBlindBox.getBlindBox();
  111. List<Collection> list =
  112. collectionRepo.findAllById(createBlindBox.getItems().stream().map(BlindBoxItem::getCollectionId)
  113. .collect(Collectors.toSet()));
  114. for (BlindBoxItem item : createBlindBox.getItems()) {
  115. Collection collection = list.stream().filter(i -> i.getId().equals(item.getCollectionId())).findAny()
  116. .orElseThrow(new BusinessException("所选藏品不存在"));
  117. if (item.getTotal() > collection.getStock()) {
  118. throw new BusinessException("所选藏品库存不足:" + collection.getName());
  119. }
  120. }
  121. User user = userRepo.findById(blindBox.getMinterId()).orElse(SecurityUtils.getAuthenticatedUser());
  122. blindBox.setMinter(user.getNickname());
  123. blindBox.setMinterId(user.getId());
  124. blindBox.setMinterAvatar(user.getAvatar());
  125. blindBox.setOwner(user.getNickname());
  126. blindBox.setOwnerId(user.getId());
  127. blindBox.setOwnerAvatar(user.getAvatar());
  128. blindBox.setStock(blindBox.getTotal());
  129. blindBox.setSale(0);
  130. collectionRepo.save(blindBox);
  131. for (BlindBoxItem item : createBlindBox.getItems()) {
  132. Collection collection = list.stream().filter(i -> i.getId().equals(item.getCollectionId())).findAny()
  133. .orElseThrow(new BusinessException("所选藏品不存在"));
  134. collection.setStock(collection.getStock() - item.getTotal());
  135. collectionRepo.save(collection);
  136. BlindBoxItem blindBoxItem = new BlindBoxItem();
  137. BeanUtils.copyProperties(collection, blindBoxItem);
  138. blindBoxItem.setId(null);
  139. blindBoxItem.setCollectionId(item.getCollectionId());
  140. blindBoxItem.setSale(0);
  141. blindBoxItem.setTotal(item.getTotal());
  142. blindBoxItem.setStock(item.getTotal());
  143. blindBoxItem.setRare(item.isRare());
  144. blindBoxItem.setBlindBoxId(blindBox.getId());
  145. blindBoxItemRepo.save(blindBoxItem);
  146. }
  147. return blindBox;
  148. }
  149. public void appointment(Long id, Long userId) {
  150. Collection collection = collectionRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  151. if (collection.getType() != CollectionType.BLIND_BOX) {
  152. throw new BusinessException("非盲盒,无需预约");
  153. }
  154. if (collection.getStartTime().isBefore(LocalDateTime.now())) {
  155. throw new BusinessException("盲盒已开售,无需预约");
  156. }
  157. appointmentRepo.save(Appointment.builder()
  158. .userId(userId)
  159. .blindBoxId(id)
  160. .build());
  161. }
  162. @Scheduled(fixedRate = 60000)
  163. public void scheduleOnShelf() {
  164. List<Collection> collections = collectionRepo.findByScheduleSaleTrueAndOnShelfFalseAndStartTimeBeforeAndDelFalse(LocalDateTime.now());
  165. for (Collection collection : collections) {
  166. collection.setOnShelf(true);
  167. }
  168. collectionRepo.saveAll(collections);
  169. }
  170. }