AssetService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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.AssetStatus;
  6. import com.izouma.nineth.enums.CollectionSource;
  7. import com.izouma.nineth.enums.CollectionType;
  8. import com.izouma.nineth.enums.OrderStatus;
  9. import com.izouma.nineth.event.TransferAssetEvent;
  10. import com.izouma.nineth.exception.BusinessException;
  11. import com.izouma.nineth.lock.RedisLockable;
  12. import com.izouma.nineth.repo.*;
  13. import com.izouma.nineth.utils.JpaUtils;
  14. import com.izouma.nineth.utils.SecurityUtils;
  15. import lombok.AllArgsConstructor;
  16. import lombok.extern.slf4j.Slf4j;
  17. import org.springframework.beans.BeanUtils;
  18. import org.springframework.context.ApplicationContext;
  19. import org.springframework.data.domain.Page;
  20. import org.springframework.scheduling.annotation.Async;
  21. import org.springframework.scheduling.annotation.AsyncResult;
  22. import org.springframework.stereotype.Service;
  23. import java.math.BigDecimal;
  24. import java.time.LocalDateTime;
  25. import java.util.ArrayList;
  26. import java.util.List;
  27. import java.util.concurrent.Future;
  28. @Service
  29. @AllArgsConstructor
  30. @Slf4j
  31. public class AssetService {
  32. private AssetRepo assetRepo;
  33. private UserRepo userRepo;
  34. private CollectionRepo collectionRepo;
  35. private ApplicationContext applicationContext;
  36. private OrderRepo orderRepo;
  37. private TokenHistoryRepo tokenHistoryRepo;
  38. private AssetMintService assetMintService;
  39. public Page<Asset> all(PageQuery pageQuery) {
  40. return assetRepo.findAll(JpaUtils.toSpecification(pageQuery, Asset.class), JpaUtils.toPageRequest(pageQuery));
  41. }
  42. @Async
  43. public Future<Asset> createAsset(Collection collection, User user, Long orderId, BigDecimal price, String type, Integer number) {
  44. Asset asset = Asset.create(collection, user);
  45. asset.setNumber(number);
  46. asset.setOrderId(orderId);
  47. asset.setPrice(price);
  48. asset.setIpfsUrl(assetMintService.ipfsUpload(collection.getPic().get(0).getUrl()));
  49. assetRepo.save(asset);
  50. TokenHistory tokenHistory = tokenHistoryRepo.save(TokenHistory.builder()
  51. .tokenId(asset.getTokenId())
  52. .fromUser(collection.getMinter())
  53. .fromUserId(collection.getMinterId())
  54. .toUser(user.getNickname())
  55. .toUserId(user.getId())
  56. .operation(type)
  57. .price(price)
  58. .build());
  59. assetMintService.mint(asset, tokenHistory.getId());
  60. return new AsyncResult<>(asset);
  61. }
  62. @Async
  63. public Future<Asset> createAsset(BlindBoxItem winItem, User user, Long orderId, BigDecimal price, String type, Integer number) {
  64. Asset asset = Asset.create(winItem, user);
  65. asset.setNumber(number);
  66. asset.setOrderId(orderId);
  67. asset.setPrice(price);
  68. asset.setIpfsUrl(assetMintService.ipfsUpload(winItem.getPic().get(0).getUrl()));
  69. assetRepo.save(asset);
  70. TokenHistory tokenHistory = tokenHistoryRepo.save(TokenHistory.builder()
  71. .tokenId(asset.getTokenId())
  72. .fromUser(winItem.getMinter())
  73. .fromUserId(winItem.getMinterId())
  74. .toUser(user.getNickname())
  75. .toUserId(user.getId())
  76. .operation(type)
  77. .price(price)
  78. .build());
  79. assetMintService.mint(asset, tokenHistory.getId());
  80. return new AsyncResult<>(asset);
  81. }
  82. public void publicShow(Long id) {
  83. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  84. if (asset.isPublicShow()) {
  85. return;
  86. }
  87. if (asset.getStatus() != AssetStatus.NORMAL) {
  88. throw new BusinessException("当前状态不可展示");
  89. }
  90. User owner = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  91. Collection collection = Collection.builder()
  92. .name(asset.getName())
  93. .pic(asset.getPic())
  94. .minter(asset.getMinter())
  95. .minterId(asset.getMinterId())
  96. .minterAvatar(asset.getMinterAvatar())
  97. .owner(owner.getNickname())
  98. .ownerId(owner.getId())
  99. .ownerAvatar(owner.getAvatar())
  100. .detail(asset.getDetail())
  101. .type(CollectionType.DEFAULT)
  102. .source(CollectionSource.TRANSFER)
  103. .sale(0)
  104. .stock(1)
  105. .total(1)
  106. .onShelf(true)
  107. .salable(false)
  108. .price(BigDecimal.valueOf(0))
  109. .properties(asset.getProperties())
  110. .canResale(asset.isCanResale())
  111. .royalties(asset.getRoyalties())
  112. .serviceCharge(asset.getServiceCharge())
  113. .assetId(id)
  114. .number(asset.getNumber())
  115. .build();
  116. collectionRepo.save(collection);
  117. asset.setPublicShow(true);
  118. asset.setPublicCollectionId(collection.getId());
  119. assetRepo.save(asset);
  120. }
  121. public void consignment(Long id, BigDecimal price) {
  122. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  123. if (asset.isConsignment()) {
  124. throw new BusinessException("已寄售,请勿重新操作");
  125. }
  126. if (asset.getStatus() != AssetStatus.NORMAL) {
  127. throw new BusinessException("当前状态不可寄售");
  128. }
  129. if (asset.isPublicShow()) {
  130. cancelPublic(asset);
  131. }
  132. User owner = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  133. Collection collection = Collection.builder()
  134. .name(asset.getName())
  135. .pic(asset.getPic())
  136. .minter(asset.getMinter())
  137. .minterId(asset.getMinterId())
  138. .minterAvatar(asset.getMinterAvatar())
  139. .owner(owner.getNickname())
  140. .ownerId(owner.getId())
  141. .ownerAvatar(owner.getAvatar())
  142. .detail(asset.getDetail())
  143. .type(CollectionType.DEFAULT)
  144. .source(CollectionSource.TRANSFER)
  145. .sale(0)
  146. .stock(1)
  147. .total(1)
  148. .onShelf(true)
  149. .salable(true)
  150. .price(price)
  151. .properties(asset.getProperties())
  152. .canResale(asset.isCanResale())
  153. .royalties(asset.getRoyalties())
  154. .serviceCharge(asset.getServiceCharge())
  155. .assetId(id)
  156. .number(asset.getNumber())
  157. .build();
  158. collectionRepo.save(collection);
  159. asset.setPublicShow(true);
  160. asset.setConsignment(true);
  161. asset.setPublicCollectionId(collection.getId());
  162. asset.setSellPrice(price);
  163. assetRepo.save(asset);
  164. }
  165. public void cancelConsignment(Long id) {
  166. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  167. cancelConsignment(asset);
  168. }
  169. public void cancelConsignment(Asset asset) {
  170. if (asset.getPublicCollectionId() != null) {
  171. List<Order> orders = orderRepo.findByCollectionId(asset.getPublicCollectionId());
  172. if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) {
  173. throw new BusinessException("已有订单不可取消");
  174. }
  175. collectionRepo.findById(asset.getPublicCollectionId())
  176. .ifPresent(collection -> {
  177. collection.setSalable(false);
  178. collectionRepo.save(collection);
  179. });
  180. }
  181. asset.setConsignment(false);
  182. assetRepo.save(asset);
  183. }
  184. public void cancelPublic(Long id) {
  185. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  186. cancelPublic(asset);
  187. }
  188. public void cancelPublic(Asset asset) {
  189. if (!asset.isPublicShow()) {
  190. return;
  191. }
  192. if (asset.isConsignment()) {
  193. cancelConsignment(asset);
  194. }
  195. Collection collection = collectionRepo.findById(asset.getPublicCollectionId())
  196. .orElseThrow(new BusinessException("无展示记录"));
  197. collectionRepo.delete(collection);
  198. asset.setPublicShow(false);
  199. asset.setCollectionId(null);
  200. assetRepo.save(asset);
  201. }
  202. public void usePrivilege(Long assetId, Long privilegeId) {
  203. Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("无记录"));
  204. asset.getPrivileges().stream().filter(p -> p.getId().equals(privilegeId)).forEach(p -> {
  205. p.setOpened(true);
  206. p.setOpenTime(LocalDateTime.now());
  207. p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId());
  208. });
  209. assetRepo.save(asset);
  210. }
  211. @Async
  212. public void transfer(Asset asset, BigDecimal price, User toUser, String reason, Long orderId) {
  213. Asset newAsset = new Asset();
  214. BeanUtils.copyProperties(asset, newAsset);
  215. newAsset.setId(null);
  216. newAsset.setUserId(toUser.getId());
  217. newAsset.setOwner(toUser.getNickname());
  218. newAsset.setOwnerId(toUser.getId());
  219. newAsset.setOwnerAvatar(toUser.getAvatar());
  220. newAsset.setPublicShow(false);
  221. newAsset.setConsignment(false);
  222. newAsset.setPublicCollectionId(null);
  223. newAsset.setStatus(AssetStatus.NORMAL);
  224. newAsset.setPrice(price);
  225. newAsset.setSellPrice(null);
  226. newAsset.setOrderId(orderId);
  227. assetRepo.save(newAsset);
  228. asset.setPublicShow(false);
  229. asset.setConsignment(false);
  230. asset.setPublicCollectionId(null);
  231. asset.setStatus(AssetStatus.GIFTED);
  232. asset.setOwner(toUser.getNickname());
  233. asset.setOwnerId(toUser.getId());
  234. asset.setOwnerAvatar(toUser.getAvatar());
  235. assetRepo.save(asset);
  236. tokenHistoryRepo.save(TokenHistory.builder()
  237. .tokenId(asset.getTokenId())
  238. .fromUser(asset.getOwner())
  239. .fromUserId(asset.getOwnerId())
  240. .toUser(toUser.getNickname())
  241. .toUserId(toUser.getId())
  242. .operation(reason)
  243. .build());
  244. if (orderId != null) {
  245. applicationContext.publishEvent(new TransferAssetEvent(this, true, newAsset));
  246. }
  247. }
  248. public List<TokenHistory> tokenHistory(String tokenId, Long assetId) {
  249. if (tokenId == null) {
  250. if (assetId == null) return new ArrayList<>();
  251. tokenId = assetRepo.findById(assetId).map(Asset::getTokenId).orElse(null);
  252. }
  253. if (tokenId == null) return new ArrayList<>();
  254. return tokenHistoryRepo.findByTokenIdOrderByCreatedAtDesc(tokenId);
  255. }
  256. @RedisLockable(key = "#id", expiration = 60, isWaiting = true)
  257. public void testLock(String id, String i) throws InterruptedException {
  258. Thread.sleep(1000);
  259. log.info("" + i);
  260. }
  261. }