AirDropService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. package com.izouma.nineth.service;
  2. import com.izouma.nineth.TokenHistory;
  3. import com.izouma.nineth.domain.*;
  4. import com.izouma.nineth.dto.PageQuery;
  5. import com.izouma.nineth.enums.AirDropType;
  6. import com.izouma.nineth.enums.CollectionType;
  7. import com.izouma.nineth.exception.BusinessException;
  8. import com.izouma.nineth.repo.*;
  9. import com.izouma.nineth.utils.JpaUtils;
  10. import lombok.extern.slf4j.Slf4j;
  11. import org.apache.commons.lang3.ObjectUtils;
  12. import org.springframework.beans.BeanUtils;
  13. import org.springframework.beans.factory.annotation.Autowired;
  14. import org.springframework.context.annotation.Lazy;
  15. import org.springframework.data.domain.Page;
  16. import org.springframework.scheduling.annotation.Async;
  17. import org.springframework.stereotype.Service;
  18. import java.time.LocalDateTime;
  19. import java.util.List;
  20. import java.util.stream.Collectors;
  21. @Service
  22. @Slf4j
  23. public class AirDropService {
  24. @Autowired
  25. private AirDropRepo airDropRepo;
  26. @Autowired
  27. private CouponRepo couponRepo;
  28. @Autowired
  29. private UserCouponRepo userCouponRepo;
  30. @Autowired
  31. private CollectionRepo collectionRepo;
  32. @Autowired
  33. private UserRepo userRepo;
  34. @Lazy
  35. @Autowired
  36. private AssetService assetService;
  37. @Autowired
  38. private CollectionService collectionService;
  39. @Autowired
  40. private ShowroomService showroomService;
  41. @Autowired
  42. private TokenHistoryRepo tokenHistoryRepo;
  43. @Autowired
  44. private AssetRepo assetRepo;
  45. @Autowired
  46. private CollectionPrivilegeRepo collectionPrivilegeRepo;
  47. public Page<AirDrop> all(PageQuery pageQuery) {
  48. return airDropRepo
  49. .findAll(JpaUtils.toSpecification(pageQuery, AirDrop.class), JpaUtils.toPageRequest(pageQuery));
  50. }
  51. public AirDrop create(AirDrop record) {
  52. if (record.getTargets().isEmpty()) throw new BusinessException("空投对象不能为空");
  53. if (record.getTargets().stream().mapToInt(DropTarget::getNum).sum() > 300)
  54. throw new BusinessException("空投数量不能超过300");
  55. if (AirDropType.coupon == record.getType()) {
  56. Coupon coupon = couponRepo.findById(record.getCouponId()).orElseThrow(new BusinessException("兑换券不存在"));
  57. for (DropTarget target : record.getTargets()) {
  58. for (int i = 0; i < target.getNum(); i++) {
  59. UserCoupon userCoupon = new UserCoupon();
  60. BeanUtils.copyProperties(coupon, userCoupon);
  61. userCoupon.setId(null);
  62. userCoupon.setCouponId(coupon.getId());
  63. userCoupon.setUserId(target.getUserId());
  64. userCouponRepo.save(userCoupon);
  65. }
  66. }
  67. } else {
  68. Collection collection = collectionRepo.findById(record.getCollectionId())
  69. .orElseThrow(new BusinessException("藏品不存在"));
  70. if (collection.isSalable()) {
  71. throw new BusinessException("请先设置藏品为不可购买");
  72. }
  73. if (!record.isIgnoreStockCheck() && collection.getStock() < record.getTargets().stream().mapToInt(DropTarget::getNum).sum()) {
  74. throw new BusinessException("藏品库存不足");
  75. }
  76. List<User> users = userRepo.findByIdInAndDelFalse(record.getTargets().stream()
  77. .map(DropTarget::getUserId).collect(Collectors.toList()));
  78. record.getTargets().parallelStream().forEach(target -> {
  79. User user = users.stream().filter(u -> u.getId().equals(target.getUserId()))
  80. .findFirst().orElse(null);
  81. if (user == null) return;
  82. try {
  83. for (int i = 0; i < target.getNum(); i++) {
  84. if (collection.getType() == CollectionType.BLIND_BOX) {
  85. BlindBoxItem winItem = collectionService.draw(target.getUserId(), collection.getId());
  86. if (record.isSimulateOrder()) {
  87. assetService.createAsset(winItem, user, 0L, collection.getPrice(), "出售",
  88. winItem.getTotal() > 1 ?
  89. collectionService.getNextNumber(winItem.getCollectionId()) : null,
  90. collection.getHoldDays(), false);
  91. } else {
  92. //查看有无vip权限
  93. CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo
  94. .findByCollectionId(record.getCollectionId());
  95. if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
  96. if (collectionPrivilege.isVip()) {
  97. //更新vip信息
  98. userRepo.updateVipPurchase(user.getId(), 1);
  99. }
  100. }
  101. Asset asset = assetService.createAsset(winItem, user, null, null, "空投",
  102. winItem.getTotal() > 1 ?
  103. collectionService.getNextNumber(winItem.getCollectionId()) : null,
  104. collection.getHoldDays(), false);
  105. //铸造空投的t+0
  106. if (record.isAuto()) {
  107. assetRepo.updateHoldDays(asset.getId(), 0);
  108. log.info("合成{},T+0", asset.getId());
  109. }
  110. }
  111. } else {
  112. if (record.isSimulateOrder()) {
  113. assetService.createAsset(collection, user, 0L, collection.getPrice(),
  114. "出售", collectionService.getNextNumber(collection), false);
  115. } else {
  116. //查看有无vip权限
  117. CollectionPrivilege collectionPrivilege = collectionPrivilegeRepo
  118. .findByCollectionId(record.getCollectionId());
  119. if (ObjectUtils.isNotEmpty(collectionPrivilege)) {
  120. if (collectionPrivilege.isVip()) {
  121. //更新vip信息
  122. userRepo.updateVipPurchase(user.getId(), 1);
  123. }
  124. }
  125. Asset asset = assetService.createAsset(collection, user, null, null,
  126. "空投", collectionService.getNextNumber(collection), false);
  127. //创建展厅
  128. if (collection.getType() == CollectionType.SHOWROOM) {
  129. asset.setOasisId(record.getOasisId());
  130. showroomService.save(asset);
  131. }
  132. //铸造空投的t+0
  133. if (record.isAuto()) {
  134. assetRepo.updateHoldDays(asset.getId(), 0);
  135. log.info("合成{},T+0", asset.getId());
  136. }
  137. }
  138. }
  139. collectionService.decreaseStock(collection.getId(), 1);
  140. collectionService.increaseSale(collection.getId(), 1);
  141. }
  142. } catch (Exception e) {
  143. e.printStackTrace();
  144. log.error("空投出错", e);
  145. }
  146. });
  147. }
  148. return airDropRepo.save(record);
  149. }
  150. @Async
  151. public void asyncDrop(Long collectionId, Long userId, int num, LocalDateTime time) {
  152. drop(collectionId, userId, num, time);
  153. }
  154. public void drop(Long collectionId, Long userId, int num, LocalDateTime time) {
  155. Collection collection = collectionRepo.findById(collectionId)
  156. .orElseThrow(new BusinessException("藏品不存在"));
  157. User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
  158. try {
  159. for (int i = 0; i < num; i++) {
  160. Asset asset;
  161. if (collection.getType() == CollectionType.BLIND_BOX) {
  162. BlindBoxItem winItem = collectionService.draw(userId, collection.getId());
  163. asset = assetService.createAsset(winItem, user, 0L, collection.getPrice(), "出售",
  164. collectionService.getNextNumber(winItem), collection.getHoldDays(), true);
  165. } else {
  166. asset = assetService.createAsset(collection, user, 0L, collection.getPrice(), "出售",
  167. collectionService.getNextNumber(collection), true);
  168. }
  169. assetRepo.flush();
  170. tokenHistoryRepo.flush();
  171. asset.setCreatedAt(time.plusSeconds((long) (Math.random() * 120)));
  172. assetRepo.save(asset);
  173. for (TokenHistory tokenHistory : tokenHistoryRepo
  174. .findByTokenIdOrderByCreatedAtDesc(asset.getTokenId())) {
  175. tokenHistory.setCreatedAt(asset.getCreatedAt());
  176. tokenHistoryRepo.save(tokenHistory);
  177. }
  178. log.info("空投成功{}/{} collectionId={}, userId={}", i + 1, num, collectionId, userId);
  179. }
  180. } catch (Exception e) {
  181. log.error("空投出错", e);
  182. }
  183. }
  184. public void drop(List<Collection> collections, String phone, LocalDateTime time) {
  185. // List<Collection> collections = collectionRepo.findAllById(collectionId);
  186. User user = userRepo.findByPhoneAndDelFalse(phone).orElseThrow(new BusinessException("用户不存在"));
  187. try {
  188. for (Collection collection : collections) {
  189. Asset asset;
  190. if (collection.getType() == CollectionType.BLIND_BOX) {
  191. BlindBoxItem winItem = collectionService.draw(user.getId(), collection.getId());
  192. asset = assetService.createAsset(winItem, user, 0L, collection.getPrice(), "出售",
  193. collectionService.getNextNumber(winItem), collection.getHoldDays(), false);
  194. } else {
  195. asset = assetService.createAsset(collection, user, 0L, collection.getPrice(), "出售",
  196. collectionService.getNextNumber(collection), false);
  197. }
  198. assetRepo.flush();
  199. tokenHistoryRepo.flush();
  200. asset.setCreatedAt(time.plusSeconds((long) (Math.random() * 120)));
  201. assetRepo.save(asset);
  202. for (TokenHistory tokenHistory : tokenHistoryRepo
  203. .findByTokenIdOrderByCreatedAtDesc(asset.getTokenId())) {
  204. tokenHistory.setCreatedAt(asset.getCreatedAt());
  205. tokenHistoryRepo.save(tokenHistory);
  206. }
  207. }
  208. } catch (Exception e) {
  209. log.error("空投出错", e);
  210. }
  211. }
  212. }