package com.izouma.nineth.service; import com.izouma.nineth.domain.*; import com.izouma.nineth.dto.CollectionDTO; import com.izouma.nineth.dto.CreateBlindBox; import com.izouma.nineth.dto.PageQuery; import com.izouma.nineth.dto.UserDTO; import com.izouma.nineth.enums.CollectionType; import com.izouma.nineth.exception.BusinessException; import com.izouma.nineth.repo.BlindBoxItemRepo; import com.izouma.nineth.repo.CollectionRepo; import com.izouma.nineth.repo.LikeRepo; import com.izouma.nineth.utils.JpaUtils; import com.izouma.nineth.utils.SecurityUtils; import lombok.AllArgsConstructor; import org.apache.commons.collections.MapUtils; import org.springframework.beans.BeanUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.transaction.Transactional; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @Service @AllArgsConstructor public class CollectionService { private CollectionRepo collectionRepo; private LikeRepo likeRepo; private BlindBoxItemRepo blindBoxItemRepo; public Page all(PageQuery pageQuery) { pageQuery.getQuery().put("del", false); Specification specification = JpaUtils.toSpecification(pageQuery, Collection.class); specification = specification.and((Specification) (root, criteriaQuery, criteriaBuilder) -> { List and = new ArrayList<>(); if (!MapUtils.getString(pageQuery.getQuery(), "type", "").equals("BLIND_BOX")) { and.add(criteriaBuilder.notEqual(root.get("type"), CollectionType.BLIND_BOX)); } return criteriaBuilder.and(and.toArray(new Predicate[0])); }); return collectionRepo.findAll(specification, JpaUtils.toPageRequest(pageQuery)); } public Collection create(Collection record) { User user = SecurityUtils.getAuthenticatedUser(); record.setMinter(user.getNickname()); record.setMinterId(user.getId()); record.setMinterAvatar(user.getAvatar()); record.setStock(record.getTotal()); record.setSale(0); return collectionRepo.save(record); } public CollectionDTO toDTO(Collection collection) { return toDTO(collection, true); } public CollectionDTO toDTO(Collection collection, boolean join) { CollectionDTO collectionDTO = new CollectionDTO(); BeanUtils.copyProperties(collection, collectionDTO); if (join) { if (SecurityUtils.getAuthenticatedUser() != null) { List list = likeRepo.findByUserIdAndCollectionId(SecurityUtils.getAuthenticatedUser().getId(), collection.getId()); collectionDTO.setLiked(!list.isEmpty()); } } return collectionDTO; } public List toDTO(List collections) { List likes = new ArrayList<>(); if (SecurityUtils.getAuthenticatedUser() != null) { likes.addAll(likeRepo.findByUserId(SecurityUtils.getAuthenticatedUser().getId())); } return collections.stream().parallel().map(collection -> { CollectionDTO dto = toDTO(collection, false); if (!likes.isEmpty()) { dto.setLiked(likes.stream().anyMatch(l -> l.getCollectionId().equals(collection.getId()))); } return dto; }).collect(Collectors.toList()); } public Page toDTO(Page collections) { List userDTOS = toDTO(collections.getContent()); return new PageImpl<>(userDTOS, collections.getPageable(), collections.getTotalElements()); } @Transactional public Collection createBlindBox(CreateBlindBox createBlindBox) { Collection blindBox = createBlindBox.getBlindBox(); List list = new ArrayList<>(); createBlindBox.getItems().stream().parallel().forEach(item -> { Collection collection = collectionRepo.findById(item.getId()).orElseThrow(new BusinessException("所选藏品不存在")); list.add(collection); if (item.getTotal() > collection.getStock()) { throw new BusinessException("所选藏品库存不足"); } }); User user = SecurityUtils.getAuthenticatedUser(); blindBox.setMinter(user.getNickname()); blindBox.setMinterId(user.getId()); blindBox.setMinterAvatar(user.getAvatar()); collectionRepo.save(blindBox); createBlindBox.getItems().stream().parallel().forEach(item -> { Collection collection = list.stream().filter(i -> i.getId().equals(item.getId())).findAny().get(); collection.setStock(collection.getStock() - item.getTotal()); collectionRepo.save(collection); BlindBoxItem blindBoxItem = new BlindBoxItem(); BeanUtils.copyProperties(collection, blindBoxItem); blindBoxItem.setCollectionId(collection.getId()); blindBoxItem.setId(null); blindBoxItem.setSale(0); blindBoxItem.setTotal(item.getTotal()); blindBoxItem.setStock(item.getTotal()); blindBoxItem.setRare(item.isRare()); blindBoxItem.setBlindBoxId(blindBox.getId()); blindBoxItemRepo.save(blindBoxItem); }); return blindBox; } }