Explorar el Código

Merge branch 'dev' into pai_mai

licailing hace 3 años
padre
commit
45b0056af1
Se han modificado 23 ficheros con 321 adiciones y 96 borrados
  1. 5 0
      src/main/java/com/izouma/nineth/domain/Asset.java
  2. 6 0
      src/main/java/com/izouma/nineth/domain/Collection.java
  3. 4 0
      src/main/java/com/izouma/nineth/domain/Order.java
  4. 2 0
      src/main/java/com/izouma/nineth/domain/User.java
  5. 1 0
      src/main/java/com/izouma/nineth/dto/PayQuery.java
  6. 25 0
      src/main/java/com/izouma/nineth/event/MintedEvent.java
  7. 5 0
      src/main/java/com/izouma/nineth/listener/MintListener.java
  8. 5 0
      src/main/java/com/izouma/nineth/repo/WithdrawApplyRepo.java
  9. 25 0
      src/main/java/com/izouma/nineth/service/AssetMintService.java
  10. 85 0
      src/main/java/com/izouma/nineth/service/HCChainService.java
  11. 0 16
      src/main/java/com/izouma/nineth/service/NFTService.java
  12. 23 20
      src/main/java/com/izouma/nineth/service/OrderService.java
  13. 5 2
      src/main/java/com/izouma/nineth/service/SandPayService.java
  14. 1 2
      src/main/java/com/izouma/nineth/service/UserBankCardService.java
  15. 0 10
      src/main/java/com/izouma/nineth/service/UserService.java
  16. 27 4
      src/main/java/com/izouma/nineth/service/WithdrawApplyService.java
  17. 1 1
      src/main/java/com/izouma/nineth/web/TestClassController.java
  18. 6 0
      src/main/java/com/izouma/nineth/web/WithdrawApplyController.java
  19. 7 0
      src/test/java/com/izouma/nineth/CommonTest.java
  20. 20 41
      src/test/java/com/izouma/nineth/PayOrderTest.java
  21. 16 0
      src/test/java/com/izouma/nineth/service/HCChainServiceTest.java
  22. 18 0
      src/test/java/com/izouma/nineth/service/SandPayServiceTest.java
  23. 34 0
      src/test/java/com/izouma/nineth/service/WithdrawApplyServiceTest.java

+ 5 - 0
src/main/java/com/izouma/nineth/domain/Asset.java

@@ -203,6 +203,11 @@ public class Asset extends CollectionBaseEntity {
     @JsonView(View.Detail.class)
     private Set<Tag> tags = new HashSet<>();
 
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
+    private String     hcTokenId;
+
     public static Asset create(Collection collection, User user) {
         return Asset.builder()
                 .userId(user.getId())

+ 6 - 0
src/main/java/com/izouma/nineth/domain/Collection.java

@@ -22,6 +22,7 @@ import org.hibernate.annotations.Formula;
 
 import javax.persistence.*;
 import java.math.BigDecimal;
+import java.math.BigInteger;
 import java.time.LocalDateTime;
 import java.util.HashSet;
 import java.util.List;
@@ -259,4 +260,9 @@ public class Collection extends CollectionBaseEntity {
     @ApiModelProperty("活动规则")
     @Column(columnDefinition = "TEXT")
     private String rule;
+
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
+    private String     hcTokenId;
 }

+ 4 - 0
src/main/java/com/izouma/nineth/domain/Order.java

@@ -209,4 +209,8 @@ public class Order extends BaseEntityNoID {
 
     @ApiModelProperty("vip积分购买")
     private Integer vipPoint;
+
+    private String     hcTxHash;
+    private BigInteger hcBlockNumber;
+    private BigInteger hcGasUsed;
 }

+ 2 - 0
src/main/java/com/izouma/nineth/domain/User.java

@@ -179,4 +179,6 @@ public class User extends UserBaseEntity implements Serializable {
 
     @Column(columnDefinition = "tinyint unsigned default 0")
     private boolean walletEnabled = false;
+
+    private String hcChainAddress;
 }

+ 1 - 0
src/main/java/com/izouma/nineth/dto/PayQuery.java

@@ -18,6 +18,7 @@ public class PayQuery {
     private boolean       exist;
     private String        msg;
     private PayStatus     status;
+    private String        orderId;
     private BigDecimal    amount;
     private LocalDateTime createTime;
     private LocalDateTime payTime;

+ 25 - 0
src/main/java/com/izouma/nineth/event/MintedEvent.java

@@ -0,0 +1,25 @@
+package com.izouma.nineth.event;
+
+import com.izouma.nineth.dto.NFT;
+import org.springframework.context.ApplicationEvent;
+
+public class MintedEvent extends ApplicationEvent {
+
+    private final Long assetId;
+    private final NFT  nft;
+
+
+    public MintedEvent(Object source, Long assetId, NFT nft) {
+        super(source);
+        this.assetId = assetId;
+        this.nft = nft;
+    }
+
+    public Long getAssetId() {
+        return assetId;
+    }
+
+    public NFT getNft() {
+        return nft;
+    }
+}

+ 5 - 0
src/main/java/com/izouma/nineth/listener/MintListener.java

@@ -27,5 +27,10 @@ public class MintListener implements RocketMQListener<Long> {
         } catch (Exception e) {
             log.error("铸造失败 " + assetId, e);
         }
+        try {
+            assetMintService.hcMint(assetId);
+        } catch (Exception e) {
+            log.error("铸造失败 " + assetId, e);
+        }
     }
 }

+ 5 - 0
src/main/java/com/izouma/nineth/repo/WithdrawApplyRepo.java

@@ -8,6 +8,7 @@ import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
 import javax.transaction.Transactional;
+import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -20,4 +21,8 @@ public interface WithdrawApplyRepo extends JpaRepository<WithdrawApply, Long>, J
     int countByUserIdAndCreatedAtBetween(Long userId, LocalDateTime start, LocalDateTime end);
 
     List<WithdrawApply> findByCreatedAtBetweenAndStatus(LocalDateTime start, LocalDateTime end, WithdrawStatus status);
+
+    List<WithdrawApply> findByCreatedAtBeforeAndStatus(LocalDateTime start, WithdrawStatus status);
+
+    List<WithdrawApply> findByStatusAndAmountLessThanEqual(WithdrawStatus status, BigDecimal amount);
 }

+ 25 - 0
src/main/java/com/izouma/nineth/service/AssetMintService.java

@@ -6,6 +6,7 @@ import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.NFT;
 import com.izouma.nineth.dto.NFTAccount;
 import com.izouma.nineth.event.CreateAssetEvent;
+import com.izouma.nineth.event.MintedEvent;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.AssetRepo;
 import com.izouma.nineth.repo.UserRepo;
@@ -35,6 +36,7 @@ public class AssetMintService {
     private ApplicationContext applicationContext;
     private Environment        env;
     private UserService        userService;
+    private HCChainService     hcChainService;
 
     @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 1000))
     public void mint(Long assetId) {
@@ -67,6 +69,29 @@ public class AssetMintService {
         }
     }
 
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 1000))
+    public void hcMint(Long assetId) {
+        Asset asset = assetRepo.findById(assetId).orElseThrow(new BusinessException("asset不存在"));
+        User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));
+        if (StringUtils.isEmpty(user.getHcChainAddress())) {
+            user.setHcChainAddress(hcChainService.createAccount(user.getId()));
+            userService.save(user);
+        }
+        try {
+            NFT nft = hcChainService.mint(user.getHcChainAddress(), asset.getTokenId());
+            asset.setHcTokenId(nft.getTokenId());
+            asset.setHcBlockNumber(nft.getBlockNumber());
+            asset.setHcTxHash(nft.getTxHash());
+            asset.setHcGasUsed(nft.getGasUsed());
+            if (asset.getIpfsUrl() == null) {
+                asset.setIpfsUrl(ipfsUpload(asset.getPic().get(0).getUrl()));
+            }
+            assetRepo.save(asset);
+            applicationContext.publishEvent(new MintedEvent(this, assetId, nft));
+        } catch (Exception e) {
+            log.error("铸造失败", e);
+        }
+    }
 //    @Async
 //    public void mint(Asset asset) {
 //        User user = userRepo.findById(asset.getUserId()).orElseThrow(new BusinessException("用户不存在"));

+ 85 - 0
src/main/java/com/izouma/nineth/service/HCChainService.java

@@ -0,0 +1,85 @@
+package com.izouma.nineth.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.nineth.dto.NFT;
+import com.izouma.nineth.exception.BusinessException;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.springframework.retry.annotation.Backoff;
+import org.springframework.retry.annotation.Retryable;
+import org.springframework.stereotype.Service;
+
+import java.math.BigInteger;
+import java.util.UUID;
+
+@Service
+@Slf4j
+@AllArgsConstructor
+public class HCChainService {
+
+    private static final String baseUrl         = "http://47.107.77.154:10000";
+    private static final String adminAddress    = "0x7c3eb0db638057af2cfbb0e7758ae37ff8dcca27";
+    private static final String contractAddress = "0xce50d8fb56f8f0d90daa8e11ca1ba125a17ce9a8";
+
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
+    public String createAccount(Long userId) {
+        String body = HttpRequest.get(baseUrl + "/api/privateKey?type=2&userName=" + UUID.randomUUID() + "&signUserId="
+                + userId + RandomStringUtils.randomAlphabetic(8) + "&appId=1&returnPrivateKey=true").body();
+        JSONObject res = JSON.parseObject(body);
+        log.info("create account result: {}", JSON.toJSONString(res, true));
+        return res.getString("address");
+    }
+
+    @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
+    public NFT mint(String address, String tokenId) {
+        String body = HttpRequest.post(baseUrl + "/api/trans/handle").contentType("application/json")
+                .send("{\n" +
+                        "    \"groupId\": \"1\",\n" +
+                        "    \"user\": \"" + adminAddress + "\",\n" +
+                        "    \"funcName\": \"mint\",\n" +
+                        "    \"funcParam\": [\n" +
+                        "        \"" + address + "\",\n" +
+                        "        \"" + new BigInteger(tokenId.replaceAll("^0x", ""), 16).toString(10) + "\"\n" +
+                        "    ],\n" +
+                        "    \"contractAddress\": \"" + contractAddress + "\",\n" +
+                        "    \"contractAbi\": [\n" +
+                        "        {\n" +
+                        "            \"inputs\": [\n" +
+                        "                {\n" +
+                        "                    \"internalType\": \"address\",\n" +
+                        "                    \"name\": \"to\",\n" +
+                        "                    \"type\": \"address\"\n" +
+                        "                },\n" +
+                        "                {\n" +
+                        "                    \"internalType\": \"uint256\",\n" +
+                        "                    \"name\": \"tokenId\",\n" +
+                        "                    \"type\": \"uint256\"\n" +
+                        "                }\n" +
+                        "            ],\n" +
+                        "            \"name\": \"mint\",\n" +
+                        "            \"outputs\": [],\n" +
+                        "            \"stateMutability\": \"nonpayable\",\n" +
+                        "            \"type\": \"function\"\n" +
+                        "        }\n" +
+                        "    ],\n" +
+                        "    \"useAes\": false,\n" +
+                        "    \"useCns\": false,\n" +
+                        "    \"cnsName\": \"\"\n" +
+                        "}").body();
+        JSONObject res = JSON.parseObject(body);
+        log.info("mint result: {}", JSON.toJSONString(res, true));
+        if ("0x0".equals(res.getString("status"))) {
+            BigInteger gas = new BigInteger(res.getString("gasUsed"));
+            String txHash = res.getString("transactionHash");
+            BigInteger blockNumber = new BigInteger(res.getString("blockNumber"));
+            return new NFT(txHash, tokenId, blockNumber, gas);
+        } else {
+            String msg = res.getString("message");
+            throw new BusinessException(msg);
+        }
+    }
+}

+ 0 - 16
src/main/java/com/izouma/nineth/service/NFTService.java

@@ -42,22 +42,6 @@ public class NFTService {
     private final ApplicationContext   context;
     private final Environment          env;
 
-    @Async
-    public void createAccount(Long userId) {
-        NFTAccount account = null;
-        for (int i = 0; i < 10; i++) {
-            try {
-                Thread.sleep(5000);
-                account = createAccount("account_" + userId);
-                break;
-            } catch (Exception e) {
-            }
-        }
-        if (account != null) {
-            context.publishEvent(new AccountCreatedEvent(this, userId, account));
-        }
-    }
-
     @Retryable(maxAttempts = 10, backoff = @Backoff(delay = 5000), value = BusinessException.class)
     public NFTAccount createAccount(String username) {
         CallRestBizParam callRestBizParam = CallRestBizParam.builder()

+ 23 - 20
src/main/java/com/izouma/nineth/service/OrderService.java

@@ -23,10 +23,7 @@ import com.izouma.nineth.dto.MarketSettlement;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.dto.UserBankCard;
 import com.izouma.nineth.enums.*;
-import com.izouma.nineth.event.CreateAssetEvent;
-import com.izouma.nineth.event.CreateOrderEvent;
-import com.izouma.nineth.event.OrderNotifyEvent;
-import com.izouma.nineth.event.TransferAssetEvent;
+import com.izouma.nineth.event.*;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.security.Authority;
@@ -265,27 +262,20 @@ public class OrderService {
                 throw new BusinessException("该藏品当前不可购买");
             }
 
-
-            AtomicInteger userMax = new AtomicInteger();
-            userPropertyRepo.findById(userId).ifPresent(userProperty -> userMax.set(userProperty.getMaxCount()));
-
             if (collection.getMaxCount() > 0) {
+                int userMax = userPropertyRepo.findById(userId)
+                        .map(UserProperty::getMaxCount)
+                        .orElse(collection.getMaxCount());
                 int count;
                 if (StringUtils.isNotBlank(collection.getCountId())) {
-                    count = orderRepo.countByUserIdAndCountIdAndStatusIn(userId, collection.getCountId(), Arrays
-                            .asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
+                    count = orderRepo.countByUserIdAndCountIdAndStatusIn(userId, collection.getCountId(),
+                            Arrays.asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
                 } else {
-                    count = orderRepo.countByUserIdAndCollectionIdAndStatusIn(userId, collectionId, Arrays
-                            .asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
+                    count = orderRepo.countByUserIdAndCollectionIdAndStatusIn(userId, collectionId,
+                            Arrays.asList(OrderStatus.FINISH, OrderStatus.NOT_PAID, OrderStatus.PROCESSING));
                 }
-                if (userMax.get() > 0) {
-                    if (count >= userMax.get()) {
-                        throw new BusinessException("限购" + userMax.get() + "件");
-                    }
-                } else {
-                    if (count >= collection.getMaxCount()) {
-                        throw new BusinessException("限购" + collection.getMaxCount() + "件");
-                    }
+                if (count >= userMax) {
+                    throw new BusinessException("限购" + userMax + "件");
                 }
 
             }
@@ -776,6 +766,19 @@ public class OrderService {
         }
     }
 
+    @EventListener
+    public void onHcMinted(MintedEvent event) {
+        Asset asset = assetRepo.findById(event.getAssetId()).orElse(null);
+        if (asset != null && asset.getOrderId() != null) {
+            orderRepo.findById(asset.getOrderId()).ifPresent(order -> {
+                order.setHcTxHash(asset.getTxHash());
+                order.setHcGasUsed(asset.getGasUsed());
+                order.setHcBlockNumber(asset.getBlockNumber());
+                orderRepo.save(order);
+            });
+        }
+    }
+
     @EventListener
     public void onTransferAsset(TransferAssetEvent event) {
         Asset asset = event.getAsset();

+ 5 - 2
src/main/java/com/izouma/nineth/service/SandPayService.java

@@ -161,7 +161,7 @@ public class SandPayService {
 
         JSONObject body = new JSONObject();
         body.put("payTool", "0401");                                  //支付工具: 固定填写0401
-        body.put("orderCode", orderId);                               //商户订单号
+        body.put("orderCode", pOrderId);                              //商户订单号
         body.put("totalAmount", convertAmount(amount));               //订单金额 12位长度,精确到分
         //body.put("limitPay", "5");                                  //限定支付方式 送1-限定不能使用贷记卡	送4-限定不能使用花呗	送5-限定不能使用贷记卡+花呗
         body.put("subject", subject);                                 //订单标题
@@ -204,7 +204,7 @@ public class SandPayService {
         header.put("productId", "00000008");                  //产品编码
 
         JSONObject body = new JSONObject();
-        body.put("orderCode", orderId);                                           //商户订单号
+        body.put("orderCode", pOrderId);                                          //商户订单号
         body.put("totalAmount", convertAmount(amount));                           //订单金额
         body.put("subject", subject);                                             //订单标题
         body.put("body", subject);                                                //订单描述
@@ -508,6 +508,9 @@ public class SandPayService {
             if (StringUtils.isNotEmpty(body.getString("payTime"))) {
                 query.setPayTime(LocalDateTime.parse(body.getString("payTime"), DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
             }
+            if (StringUtils.isNotEmpty(body.getString("oriOrderCode"))) {
+                query.setOrderId(body.getString("oriOrderCode"));
+            }
             switch (body.getString("orderStatus")) {
                 case "00":
                     query.setStatus(PayStatus.SUCCESS);

+ 1 - 2
src/main/java/com/izouma/nineth/service/UserBankCardService.java

@@ -77,8 +77,7 @@ public class UserBankCardService {
         payEaseService.bindCardCaptcha(bindCardId);
     }
 
-    public void
-    unbind(Long userId) {
+    public void unbind(Long userId) {
         User user = userRepo.findById(userId).orElseThrow(new BusinessException("用户不存在"));
         userBankCardRepo.findByUserId(userId).forEach(userBankCard -> {
             if (StringUtils.isNotEmpty(userBankCard.getBindCardId())) {

+ 0 - 10
src/main/java/com/izouma/nineth/service/UserService.java

@@ -231,16 +231,6 @@ public class UserService {
         return save(user);
     }
 
-    @EventListener
-    public void accountCreated(AccountCreatedEvent event) {
-        userRepo.findById(event.getUserId()).ifPresent(user -> {
-            user.setNftAccount(event.getAccount().getAccountId());
-            user.setKmsId(event.getAccount().getAccountKmsId());
-            user.setPublicKey(event.getAccount().getPublicKey());
-            save(user);
-        });
-    }
-
     public User phoneRegister(String phone, String code, String password, String inviteCode, Long invitor, Long collectionId) {
         String name = "9th_" + RandomStringUtils.randomAlphabetic(8);
         Invite invite = null;

+ 27 - 4
src/main/java/com/izouma/nineth/service/WithdrawApplyService.java

@@ -16,6 +16,7 @@ import com.izouma.nineth.repo.WithdrawApplyRepo;
 import com.izouma.nineth.utils.JpaUtils;
 import com.izouma.nineth.utils.SnowflakeIdWorker;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.redisson.api.RLock;
 import org.redisson.api.RedissonClient;
@@ -25,6 +26,7 @@ import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
@@ -37,6 +39,7 @@ import java.util.regex.Pattern;
 
 @Service
 @AllArgsConstructor
+@Slf4j
 public class WithdrawApplyService {
 
     private WithdrawApplyRepo  withdrawApplyRepo;
@@ -61,7 +64,7 @@ public class WithdrawApplyService {
         }
         int limit = sysConfigService.getInt("daily_withdraw_limit");
         if (withdrawApplyRepo.countByUserIdAndCreatedAtBetween(userId,
-                LocalDate.now().atStartOfDay(), LocalDate.now().atTime(LocalTime.MAX)) > limit) {
+                LocalDate.now().atStartOfDay(), LocalDate.now().atTime(LocalTime.MAX)) >= limit) {
             throw new BusinessException("每天只能申请提现" + limit + "次");
         }
         userBalanceService.preWithdraw(userId, amount);
@@ -96,7 +99,8 @@ public class WithdrawApplyService {
                 String withdrawCharge = sysConfigService.getString("withdraw_charge");
                 if (StringUtils.isNotEmpty(withdrawCharge) && Pattern.matches("^(\\d+|\\d+.\\d+),\\d+$", withdrawCharge)) {
                     String[] arr = withdrawCharge.split(",");
-                    chargeAmount = new BigDecimal(arr[0]);
+                    chargeAmount = apply.getAmount().multiply(new BigDecimal(arr[0]))
+                            .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
                     BigDecimal minChargeAmount = new BigDecimal(arr[1]);
                     if (chargeAmount.compareTo(minChargeAmount) < 0) {
                         chargeAmount = minChargeAmount;
@@ -166,8 +170,8 @@ public class WithdrawApplyService {
     @RedisLock(value = "'approveAll'", expire = 1, unit = TimeUnit.HOURS)
     public void approveAll() throws ExecutionException, InterruptedException {
         new ForkJoinPool(5).submit(() -> {
-            withdrawApplyRepo.findByCreatedAtBetweenAndStatus(LocalDate.now().minusDays(1).atStartOfDay(),
-                            LocalDate.now().minusDays(1).atTime(LocalTime.MAX), WithdrawStatus.PENDING)
+            withdrawApplyRepo.findByCreatedAtBeforeAndStatus(LocalDate.now().atStartOfDay(),
+                            WithdrawStatus.PENDING)
                     .parallelStream().forEach(withdrawApply -> {
                         try {
                             finishWithdrawApply(withdrawApply.getId(), true, null);
@@ -176,4 +180,23 @@ public class WithdrawApplyService {
                     });
         }).get();
     }
+
+    @Async
+    public void fixCharge() throws ExecutionException, InterruptedException {
+        new ForkJoinPool(5).submit(() -> {
+            withdrawApplyRepo.findByStatusAndAmountLessThanEqual(WithdrawStatus.SUCCESS, new BigDecimal("1000"))
+                    .parallelStream().forEach(apply -> {
+                        try {
+                            UserBankCard bankCard = userBankCardRepo.findByUserId(apply.getUserId())
+                                    .stream().findFirst()
+                                    .orElseThrow(new BusinessException("未绑卡"));
+                            JSONObject res = sandPayService.transfer(snowflakeIdWorker.nextId() + "", bankCard.getRealName(),
+                                    bankCard.getBankNo(), new BigDecimal("6"));
+                        } catch (Exception e) {
+                            log.error("fixCharge", e);
+                        }
+                    });
+        }).get();
+
+    }
 }

+ 1 - 1
src/main/java/com/izouma/nineth/web/TestClassController.java

@@ -71,7 +71,7 @@ public class TestClassController extends BaseController {
     @GetMapping("/test")
     public String test() {
         Bucket bucket = buckets.builder().build("test1", () -> (BucketConfiguration.builder()
-                .addLimit(Bandwidth.classic(10, Refill.intervally(10, Duration.ofSeconds(10))))
+                .addLimit(Bandwidth.classic(300, Refill.intervally(300, Duration.ofSeconds(30))))
                 .build()));
         if (bucket.tryConsume(1)) {
             return "ok";

+ 6 - 0
src/main/java/com/izouma/nineth/web/WithdrawApplyController.java

@@ -61,5 +61,11 @@ public class WithdrawApplyController extends BaseController {
     public void approveAll() throws ExecutionException, InterruptedException {
         withdrawApplyService.approveAll();
     }
+
+    @PreAuthorize("hasRole('ADMIN')")
+    @PostMapping("/fixCharge")
+    public void fixCharge() throws ExecutionException, InterruptedException {
+        withdrawApplyService.fixCharge();
+    }
 }
 

+ 7 - 0
src/test/java/com/izouma/nineth/CommonTest.java

@@ -724,4 +724,11 @@ public class CommonTest {
             System.out.println(m.group(1));
         }
     }
+
+    @Test
+    public void createaccount() {
+        JSONObject jsonObject = JSON.parseObject(HttpRequest.get("http://47.107.77.154:10000/api/privateKey?type=2&userName=" + UUID.randomUUID() + "&signUserId="
+                + RandomStringUtils.randomAlphabetic(8) + "&appId=1&returnPrivateKey=true").body());
+        System.out.println(JSON.toJSONString(jsonObject, true));
+    }
 }

+ 20 - 41
src/test/java/com/izouma/nineth/PayOrderTest.java

@@ -13,47 +13,26 @@ public class PayOrderTest extends ApplicationTests {
 
     @Test
     public void refund() {
-        for (int orderId : new int[]{
-                7587002,
-                7587102,
-                7587101,
-                7587577,
-                7587001,
-                7587100,
-                7587000,
-                7587574,
-                7586999,
-                7587573,
-                7586998,
-                7586997,
-                7587571,
-                7587569,
-                7587570,
-                7587568,
-                7586996,
-                7586995,
-                7586993,
-                7587567,
-                7586916,
-                7587096,
-                7586915,
-                7586992,
-                7587094,
-                7587091,
-                7587093,
-                7587090,
-                7586991,
-                7586914,
-                7586913,
-                7587089,
-                7586990,
-                7587088,
-                7586989
-        }) {
-            PayQuery query = orderPayService.query(orderId + "");
-            if (query.isExist()) {
-                orderPayService.refund(orderId + "", query.getTransactionId(), query.getAmount(), query.getChannel());
-            }
+        for (String s : new String[]{"NUPAC20220602004158600000000000000088878",
+                "NUPAC20220602004178600000000000000089288",
+                "NUPAC20220602004199100000000000000089197",
+                "NUPAC20220602004125400000000000000090478",
+                "NUPAC20220602004178800000000000000091749",
+                "NUPAC20220602004183300000000000000093060",
+                "NUPAC20220602004131100000000000000094001",
+                "NUPAC20220602004114100000000000000093751",
+                "NUPAC20220602004195800000000000000094095",
+                "NUPAC20220602004166600000000000000095053",
+                "NUPAC20220602004171300000000000000094667",
+                "NUPAC20220602004155000000000000000095478",
+                "NUPAC20220602004198300000000000000096828",
+                "NUPAC20220602004128500000000000000098532",
+                "NUPAC20220602004129100000000000000099890",
+                "NUPAC20220602004113200000000000000099680",
+                "NUPAC20220602004170100000000000000100350"}) {
+            PayQuery q = orderPayService.query(s, Constants.PayChannel.SAND);
+            orderPayService.refund(q.getOrderId(), q.getTransactionId(), q.getAmount(), q.getChannel());
         }
+
     }
 }

+ 16 - 0
src/test/java/com/izouma/nineth/service/HCChainServiceTest.java

@@ -0,0 +1,16 @@
+package com.izouma.nineth.service;
+
+import org.junit.jupiter.api.Test;
+
+class HCChainServiceTest {
+    HCChainService hcChainService = new HCChainService();
+
+    @Test
+    public void createAccount() {
+    }
+
+    @Test
+    public void mint() {
+        hcChainService.mint("0x62e5d2ae45f9f056e71ac34c49430976b96a81b0", "0x3ce288795a3b7799c3e65345301a0e9");
+    }
+}

+ 18 - 0
src/test/java/com/izouma/nineth/service/SandPayServiceTest.java

@@ -82,6 +82,24 @@ class SandPayServiceTest {
 
     @Test
     public void refund() {
+        JSONObject header = new JSONObject();
+        header.put("version", "1.0");                           //版本号
+        header.put("method", "sandpay.trade.refund");           //接口名称:退货
+        header.put("productId", "00000006");                    //产品编码
+        header.put("mid", mid);          //商户号
+        header.put("accessType", "1");                          //接入类型设置为普通商户接入
+        header.put("channelType", "07");                        //渠道类型:07-互联网   08-移动端
+        header.put("reqTime", SandPayService.getReqTime());                    //请求时间
+
+        JSONObject body = new JSONObject();
+        body.put("orderCode", new SnowflakeIdWorker(0, 0).nextId());        //商户订单号
+        body.put("oriOrderCode", "981961667879387136");        //原交易订单号
+        body.put("refundAmount", "000000005100");          //退货金额
+        body.put("refundReason", "退款");                         //退货原因
+        body.put("notifyUrl", "https://test.raex.vip/sandpay/notify");  //异步通知地址
+        body.put("extend", "");
+
+        SandPayService.requestServer(header, body, "https://cashier.sandpay.com.cn/qr/api/order/refund");
     }
 
     @Test

+ 34 - 0
src/test/java/com/izouma/nineth/service/WithdrawApplyServiceTest.java

@@ -0,0 +1,34 @@
+package com.izouma.nineth.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.izouma.nineth.ApplicationTests;
+import com.izouma.nineth.dto.UserBankCard;
+import com.izouma.nineth.enums.WithdrawStatus;
+import com.izouma.nineth.repo.UserBankCardRepo;
+import com.izouma.nineth.repo.WithdrawApplyRepo;
+import com.izouma.nineth.utils.SnowflakeIdWorker;
+import lombok.AllArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.math.BigDecimal;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+@AllArgsConstructor
+class WithdrawApplyServiceTest extends ApplicationTests {
+    private WithdrawApplyRepo withdrawApplyRepo;
+    private UserBankCardRepo  userBankCardRepo;
+    private SandPayService    sandPayService;
+    private SnowflakeIdWorker snowflakeIdWorker;
+
+    public void fixCharge() {
+        withdrawApplyRepo.findByStatusAndAmountLessThanEqual(WithdrawStatus.SUCCESS, new BigDecimal("1000"))
+                .parallelStream().forEach(apply -> {
+                    UserBankCard bankCard = userBankCardRepo.findByUserId(apply.getUserId())
+                            .stream().findFirst()
+                            .orElse(null);
+                    JSONObject res = sandPayService.transfer(snowflakeIdWorker.nextId() + "", bankCard.getRealName(),
+                            bankCard.getBankNo(), new BigDecimal("6"));
+                });
+    }
+}