xiongzhu пре 4 година
родитељ
комит
b8b761f388

+ 40 - 4
src/main/java/com/izouma/nineth/service/AssetService.java

@@ -1,9 +1,6 @@
 package com.izouma.nineth.service;
 
-import com.izouma.nineth.domain.Asset;
-import com.izouma.nineth.domain.Collection;
-import com.izouma.nineth.domain.Order;
-import com.izouma.nineth.domain.User;
+import com.izouma.nineth.domain.*;
 import com.izouma.nineth.dto.NFT;
 import com.izouma.nineth.dto.NFTAccount;
 import com.izouma.nineth.dto.PageQuery;
@@ -74,4 +71,43 @@ public class AssetService {
         }
         applicationContext.publishEvent(new CreateAssetEvent(this, false, order, null));
     }
+
+    @Async
+    public void createAsset(Order order, BlindBoxItem winItem) {
+        User user = userRepo.findById(order.getUserId()).orElseThrow(new BusinessException("用户不存在"));
+        if (StringUtils.isEmpty(user.getPublicKey())) {
+            NFTAccount account = nftService.createAccount(user.getUsername());
+            user.setNftAccount(account.getAccountId());
+            user.setKmsId(account.getAccountKmsId());
+            user.setPublicKey(account.getPublicKey());
+            userRepo.save(user);
+        }
+        try {
+            NFT nft = nftService.createToken(user.getNftAccount());
+            if (nft != null) {
+                Asset asset = Asset.builder()
+                        .userId(user.getId())
+                        .orderId(order.getId())
+                        .minter(winItem.getMinter())
+                        .minterId(winItem.getMinterId())
+                        .minterAvatar(winItem.getMinterAvatar())
+                        .name(winItem.getName())
+                        .pic(winItem.getPics())
+                        .properties(winItem.getProperties())
+                        .tokenId(nft.getTokenId())
+                        .blockNumber(nft.getBlockNumber())
+                        .txHash(nft.getTxHash())
+                        .gasUsed(nft.getGasUsed())
+                        .price(order.getPrice())
+                        .status(AssetStatus.NORMAL)
+                        .build();
+                assetRepo.save(asset);
+                applicationContext.publishEvent(new CreateAssetEvent(this, true, order, asset));
+                return;
+            }
+        } catch (Exception e) {
+            log.error("创建token失败", e);
+        }
+        applicationContext.publishEvent(new CreateAssetEvent(this, false, order, null));
+    }
 }

+ 30 - 11
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -218,6 +218,8 @@ public class OrderService {
         if (order.getStatus() == OrderStatus.NOT_PAID) {
             if (order.getType() == CollectionType.BLIND_BOX) {
                 List<BlindBoxItem> items = blindBoxItemRepo.findByBlindBoxId(order.getCollectionId());
+
+
                 Map<BlindBoxItem, Range<Integer>> randomRange = new HashMap<>();
                 int c = 0, sum = 0;
                 for (BlindBoxItem item : items) {
@@ -226,35 +228,52 @@ public class OrderService {
                     sum += item.getStock();
                 }
 
-                boolean win = false;
                 int retry = 0;
                 BlindBoxItem winItem = null;
                 while (winItem == null) {
+                    retry++;
                     int rand = RandomUtils.nextInt(0, sum + 1);
                     for (Map.Entry<BlindBoxItem, Range<Integer>> entry : randomRange.entrySet()) {
                         BlindBoxItem item = entry.getKey();
                         Range<Integer> range = entry.getValue();
                         if (rand >= range.getMinimum() && rand < range.getMaximum()) {
+                            int total = items.stream().filter(i -> !i.isRare())
+                                    .mapToInt(BlindBoxItem::getTotal).sum();
+                            int stock = items.stream().filter(i -> !i.isRare())
+                                    .mapToInt(BlindBoxItem::getStock).sum();
                             if (item.isRare()) {
-                                int total = items.stream().filter(i -> !i.isRare())
-                                        .mapToInt(BlindBoxItem::getTotal).sum();
-                                int stock = items.stream().filter(i -> !i.isRare())
-                                        .mapToInt(BlindBoxItem::getStock).sum();
-
                                 double nRate = stock / (double) total;
+                                double rRate = (item.getStock() - 1) / (double) item.getTotal();
+
+                                if (Math.abs(nRate - rRate) < (1 / (double) item.getTotal()) || retry > 1 || rRate == 0) {
+                                    if (!(nRate > 0.1 && item.getStock() == 1)) {
+                                        winItem = item;
+                                    }
+                                }
+                            } else {
+                                double nRate = (stock - 1) / (double) total;
                                 double rRate = item.getStock() / (double) item.getTotal();
 
-                                if (Math.abs(nRate - rRate) < 0.05 || retry > 1) {
+                                if (Math.abs(nRate - rRate) < 0.2 || retry > 1 || nRate == 0) {
                                     winItem = item;
-                                } else {
-                                    retry++;
                                 }
-                            } else {
-                                winItem = item;
                             }
                         }
                     }
+
+                    if (retry > 100 && winItem == null) {
+                        throw new BusinessException("盲盒抽卡失败");
+                    }
                 }
+                winItem.setStock(winItem.getStock() - 1);
+                winItem.setSale(winItem.getSale() + 1);
+
+                order.setStatus(OrderStatus.PROCESSING);
+                order.setPayTime(LocalDateTime.now());
+                order.setTransactionId(MapUtils.getString(params, "trade_no"));
+                order.setPayMethod(PayMethod.ALIPAY);
+                orderRepo.save(order);
+                assetService.createAsset(order, winItem);
 
 
             } else {