AssetService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. package com.izouma.nineth.service;
  2. import com.github.kevinsawicki.http.HttpRequest;
  3. import com.izouma.nineth.domain.*;
  4. import com.izouma.nineth.dto.NFT;
  5. import com.izouma.nineth.dto.NFTAccount;
  6. import com.izouma.nineth.dto.PageQuery;
  7. import com.izouma.nineth.enums.AssetStatus;
  8. import com.izouma.nineth.enums.CollectionSource;
  9. import com.izouma.nineth.enums.CollectionType;
  10. import com.izouma.nineth.event.CreateAssetEvent;
  11. import com.izouma.nineth.exception.BusinessException;
  12. import com.izouma.nineth.repo.*;
  13. import com.izouma.nineth.utils.JpaUtils;
  14. import com.izouma.nineth.utils.SecurityUtils;
  15. import io.ipfs.api.IPFS;
  16. import io.ipfs.api.MerkleNode;
  17. import io.ipfs.api.NamedStreamable;
  18. import io.ipfs.multihash.Multihash;
  19. import lombok.AllArgsConstructor;
  20. import lombok.extern.slf4j.Slf4j;
  21. import org.apache.commons.lang3.StringUtils;
  22. import org.springframework.context.ApplicationContext;
  23. import org.springframework.data.domain.Page;
  24. import org.springframework.retry.annotation.Backoff;
  25. import org.springframework.retry.annotation.Retryable;
  26. import org.springframework.scheduling.annotation.Async;
  27. import org.springframework.stereotype.Service;
  28. import java.io.File;
  29. import java.math.BigDecimal;
  30. import java.time.LocalDateTime;
  31. @Service
  32. @AllArgsConstructor
  33. @Slf4j
  34. public class AssetService {
  35. private AssetRepo assetRepo;
  36. private UserRepo userRepo;
  37. private NFTService nftService;
  38. private CollectionRepo collectionRepo;
  39. private ApplicationContext applicationContext;
  40. public Page<Asset> all(PageQuery pageQuery) {
  41. return assetRepo.findAll(JpaUtils.toSpecification(pageQuery, Asset.class), JpaUtils.toPageRequest(pageQuery));
  42. }
  43. @Async
  44. public void createAsset(Order order) {
  45. User user = userRepo.findById(order.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  46. if (StringUtils.isEmpty(user.getPublicKey())) {
  47. NFTAccount account = nftService.createAccount(user.getUsername());
  48. user.setNftAccount(account.getAccountId());
  49. user.setKmsId(account.getAccountKmsId());
  50. user.setPublicKey(account.getPublicKey());
  51. userRepo.save(user);
  52. }
  53. try {
  54. NFT nft = nftService.createToken(user.getNftAccount());
  55. String ipfsUrl = ipfsUpload(order.getPic().get(0).getUrl());
  56. if (nft != null) {
  57. Asset asset = Asset.builder()
  58. .userId(user.getId())
  59. .orderId(order.getId())
  60. .collectionId(order.getCollectionId())
  61. .minter(order.getMinter())
  62. .minterId(order.getMinterId())
  63. .minterAvatar(order.getMinterAvatar())
  64. .name(order.getName())
  65. .detail(order.getDetail())
  66. .pic(order.getPic())
  67. .properties(order.getProperties())
  68. .category(order.getCategory())
  69. .canResale(order.isCanResale())
  70. .royalties(order.getRoyalties())
  71. .serviceCharge(order.getServiceCharge())
  72. .tokenId(nft.getTokenId())
  73. .blockNumber(nft.getBlockNumber())
  74. .txHash(nft.getTxHash())
  75. .gasUsed(nft.getGasUsed())
  76. .price(order.getPrice())
  77. .status(AssetStatus.NORMAL)
  78. .ipfsUrl(ipfsUrl)
  79. .number((int) (assetRepo.countByIpfsUrlAndStatusNot(ipfsUrl, AssetStatus.TRANSFERRED) + 1))
  80. .build();
  81. assetRepo.save(asset);
  82. applicationContext.publishEvent(new CreateAssetEvent(this, true, order, asset));
  83. return;
  84. }
  85. } catch (Exception e) {
  86. log.error("创建token失败", e);
  87. }
  88. applicationContext.publishEvent(new CreateAssetEvent(this, false, order, null));
  89. }
  90. @Async
  91. public void createAsset(Order order, BlindBoxItem winItem) {
  92. User user = userRepo.findById(order.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  93. if (StringUtils.isEmpty(user.getPublicKey())) {
  94. NFTAccount account = nftService.createAccount(user.getUsername());
  95. user.setNftAccount(account.getAccountId());
  96. user.setKmsId(account.getAccountKmsId());
  97. user.setPublicKey(account.getPublicKey());
  98. userRepo.save(user);
  99. }
  100. try {
  101. NFT nft = nftService.createToken(user.getNftAccount());
  102. if (nft != null) {
  103. Asset asset = Asset.builder()
  104. .userId(user.getId())
  105. .orderId(order.getId())
  106. .collectionId(order.getCollectionId())
  107. .minter(winItem.getMinter())
  108. .minterId(winItem.getMinterId())
  109. .minterAvatar(winItem.getMinterAvatar())
  110. .name(winItem.getName())
  111. .detail(winItem.getDetail())
  112. .pic(winItem.getPic())
  113. .properties(winItem.getProperties())
  114. .canResale(winItem.isCanResale())
  115. .royalties(winItem.getRoyalties())
  116. .serviceCharge(winItem.getServiceCharge())
  117. .tokenId(nft.getTokenId())
  118. .blockNumber(nft.getBlockNumber())
  119. .txHash(nft.getTxHash())
  120. .gasUsed(nft.getGasUsed())
  121. .price(order.getPrice())
  122. .status(AssetStatus.NORMAL)
  123. .ipfsUrl(ipfsUpload(winItem.getPic().get(0).getUrl()))
  124. .build();
  125. assetRepo.save(asset);
  126. applicationContext.publishEvent(new CreateAssetEvent(this, true, order, asset));
  127. return;
  128. }
  129. } catch (Exception e) {
  130. log.error("创建token失败", e);
  131. }
  132. applicationContext.publishEvent(new CreateAssetEvent(this, false, order, null));
  133. }
  134. public String ipfsUpload(String url) {
  135. try {
  136. IPFS ipfs = new IPFS("121.40.132.44", 5001);
  137. HttpRequest request = HttpRequest.get(url);
  138. File file = File.createTempFile("ipfs", ".tmp");
  139. request.receive(file);
  140. NamedStreamable.FileWrapper file1 = new NamedStreamable.FileWrapper(file);
  141. MerkleNode put = ipfs.add(file1).get(0);
  142. Multihash multihash = ipfs.pin.add(put.hash).get(0);
  143. log.info("上传ipfs成功 {}", multihash.toBase58());
  144. return multihash.toBase58();
  145. } catch (Exception e) {
  146. }
  147. return null;
  148. }
  149. public void publicShow(Long id) {
  150. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  151. if (asset.isPublicShow()) {
  152. return;
  153. }
  154. User owner = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  155. Collection collection = Collection.builder()
  156. .name(asset.getName())
  157. .pic(asset.getPic())
  158. .minter(asset.getMinter())
  159. .minterId(asset.getMinterId())
  160. .minterAvatar(asset.getMinterAvatar())
  161. .owner(owner.getNickname())
  162. .ownerId(owner.getId())
  163. .ownerAvatar(owner.getAvatar())
  164. .detail(asset.getDetail())
  165. .type(CollectionType.DEFAULT)
  166. .source(CollectionSource.TRANSFER)
  167. .sale(0)
  168. .stock(1)
  169. .total(1)
  170. .onShelf(true)
  171. .salable(false)
  172. .price(BigDecimal.valueOf(0))
  173. .properties(asset.getProperties())
  174. .canResale(asset.isCanResale())
  175. .royalties(asset.getRoyalties())
  176. .serviceCharge(asset.getServiceCharge())
  177. .assetId(id)
  178. .build();
  179. collectionRepo.save(collection);
  180. asset.setPublicShow(true);
  181. asset.setPublicCollectionId(collection.getId());
  182. assetRepo.save(asset);
  183. }
  184. public void Consignment(Long id, BigDecimal price) {
  185. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  186. Collection collection = null;
  187. if (asset.isPublicShow() && asset.getCollectionId() != null) {
  188. collection = collectionRepo.findById(asset.getCollectionId()).orElse(null);
  189. }
  190. User owner = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
  191. if (collection == null) {
  192. collection = Collection.builder()
  193. .name(asset.getName())
  194. .pic(asset.getPic())
  195. .minter(asset.getMinter())
  196. .minterId(asset.getMinterId())
  197. .minterAvatar(asset.getMinterAvatar())
  198. .owner(owner.getNickname())
  199. .ownerId(owner.getId())
  200. .ownerAvatar(owner.getAvatar())
  201. .detail(asset.getDetail())
  202. .type(CollectionType.DEFAULT)
  203. .source(CollectionSource.TRANSFER)
  204. .sale(0)
  205. .stock(1)
  206. .total(1)
  207. .onShelf(true)
  208. .salable(false)
  209. .price(BigDecimal.valueOf(0))
  210. .properties(asset.getProperties())
  211. .canResale(asset.isCanResale())
  212. .royalties(asset.getRoyalties())
  213. .serviceCharge(asset.getServiceCharge())
  214. .assetId(id)
  215. .build();
  216. }
  217. collection.setSalable(true);
  218. collection.setPrice(price);
  219. collectionRepo.save(collection);
  220. asset.setPublicShow(true);
  221. asset.setPublicCollectionId(collection.getId());
  222. assetRepo.save(asset);
  223. }
  224. public void cancelPublic(Long id) {
  225. Asset asset = assetRepo.findById(id).orElseThrow(new BusinessException("无记录"));
  226. if (!asset.isPublicShow()) {
  227. return;
  228. }
  229. Collection collection = collectionRepo.findById(asset.getPublicCollectionId())
  230. .orElseThrow(new BusinessException("无展示记录"));
  231. collectionRepo.delete(collection);
  232. asset.setPublicShow(false);
  233. asset.setCollectionId(null);
  234. assetRepo.save(asset);
  235. }
  236. public void usePrivilege(Long assetId, Long privilegeId) {
  237. Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("无记录"));
  238. asset.getPrivileges().stream().filter(p -> p.getId().equals(privilegeId)).forEach(p -> {
  239. p.setOpened(true);
  240. p.setOpenTime(LocalDateTime.now());
  241. p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId());
  242. });
  243. assetRepo.save(asset);
  244. }
  245. }