Browse Source

Merge branch 'dev' of http://git.izouma.com/xiongzhu/raex_back into dev

wangqifan 4 năm trước cách đây
mục cha
commit
b848ec716f

+ 5 - 0
src/main/java/com/izouma/nineth/config/CacheConfig.java

@@ -129,6 +129,11 @@ public class CacheConfig {
                 .entryTtl(Duration.ofDays(7))
                 .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
 
+        cacheNamesConfigurationMap.put("payOrder", RedisCacheConfiguration.defaultCacheConfig()
+                .entryTtl(Duration.ofHours(1))
+                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())));
+
+
         RedisCacheManager redisCacheManager = RedisCacheManager.builder()
                 .cacheWriter(RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory()))
                 .withInitialCacheConfigurations(cacheNamesConfigurationMap)

+ 14 - 0
src/main/java/com/izouma/nineth/config/HmPayProperties.java

@@ -0,0 +1,14 @@
+package com.izouma.nineth.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@Data
+@ConfigurationProperties(prefix = "hmpay")
+public class HmPayProperties {
+    private String merNo;
+    private String appPrivateKey;
+    private String appPublicKey;
+    private String hmPublicKey;
+    private String notifyUrl;
+}

+ 2 - 0
src/main/java/com/izouma/nineth/repo/UserBalanceRepo.java

@@ -6,6 +6,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 import org.springframework.data.jpa.repository.Modifying;
 import org.springframework.data.jpa.repository.Query;
 
+import javax.transaction.Transactional;
 import java.math.BigDecimal;
 import java.util.List;
 
@@ -17,5 +18,6 @@ public interface UserBalanceRepo extends JpaRepository<UserBalance, Long>, JpaSp
 
     @Query("update UserBalance u set u.locked = false, u.lockTime = null, u.lockReason = null where u.userId = ?1")
     @Modifying
+    @Transactional
     int unlock(Long userId);
 }

+ 1 - 0
src/main/java/com/izouma/nineth/security/WebSecurityConfig.java

@@ -119,6 +119,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
                 .antMatchers("/testClass/**").permitAll()
                 .antMatchers("/appVersion/**").permitAll()
                 .antMatchers("/sandpay/**").permitAll()
+                .antMatchers("/hmpay/**").permitAll()
                 .antMatchers("/order/calcSettle").permitAll()
                 // all other requests need to be authenticated
                 .anyRequest().authenticated().and()

+ 115 - 0
src/main/java/com/izouma/nineth/service/HMPayService.java

@@ -0,0 +1,115 @@
+package com.izouma.nineth.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.nineth.config.GeneralProperties;
+import com.izouma.nineth.config.HmPayProperties;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.utils.DateTimeUtils;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+@AllArgsConstructor
+@EnableConfigurationProperties({HmPayProperties.class})
+public class HMPayService {
+    private final HmPayProperties   hmPayProperties;
+    private final GeneralProperties generalProperties;
+
+    private String getSign(Map<String, String> params) {
+        try {
+            Map<String, String> m = new HashMap<>(params);
+            m.remove("expire_time");
+            m.remove("goods_name");
+            m.remove("product_code");
+            m.remove("clear_cycle");
+            m.remove("jump_scheme");
+            m.remove("meta_option");
+            return AlipaySignature.rsaSign(m, hmPayProperties.getAppPrivateKey(), "UTF-8");
+        } catch (AlipayApiException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private void encodeParams(Map<String, String> params) {
+        List<String> arr = Arrays.asList("notify_url", "return_url", "goods_name", "meta_option", "sign", "pay_extra");
+        params.forEach((k, v) -> {
+            if (arr.contains(k)) {
+                params.put(k, URLEncoder.encode(v, StandardCharsets.UTF_8));
+            }
+        });
+    }
+
+    public String getReqTime() {
+        return DateTimeUtils.format(LocalDateTime.now(), "yyyyMMddHHmmss");
+    }
+
+    public String getTimeout(int seconds) {
+        return DateTimeUtils.format(LocalDateTime.now().plusSeconds(seconds), "yyyyMMddHHmmss");
+    }
+
+    public JSONObject requestAlipayRaw(String orderId, BigDecimal amount, String subject,
+                                       int timeout, String type, String returnUrl) {
+        if (orderId.length() < 12) {
+            for (int i = orderId.length(); i < 12; i++) {
+                orderId = "0" + orderId;
+            }
+        }
+        Map<String, String> params = new HashMap<>();
+        params.put("version", "10");
+        params.put("mer_no", "664403000025502");
+        params.put("mer_order_no", orderId);
+        params.put("create_time", getReqTime());
+        params.put("expire_time", getTimeout(timeout));
+        params.put("order_amt", amount.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString());
+        params.put("notify_url", hmPayProperties.getNotifyUrl());
+        params.put("return_url", returnUrl);
+        params.put("create_ip", "58_213_205_43");
+        params.put("goods_name", subject);
+        params.put("store_id", "100001");
+        params.put("product_code", "01020002");
+        params.put("clear_cycle", "0"); //不参与签名
+        params.put("meta_option", "[{\"s\":\"Android\",\"n\":\"绿洲宇宙\",\"id\":\"vip.raex.nft\",\"sc\":\"wzsc://\"},{\"s\":\"IOS\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"}]"); //不参与签名
+        params.put("jump_scheme", "hemacash://hmpay");
+        params.put("sign_type", "RSA");
+        params.put("accsplit_info", "N");
+        log.info("支付请求参数: {}", JSON.toJSONString(params, true));
+        params.put("sign", getSign(params));
+        log.info("支付请求签名: {}", params.get("sign"));
+        encodeParams(params);
+
+        String body = HttpRequest.post("https://cash.sandgate.cn/gateway/api")
+                .contentType("application/json")
+                .send(JSON.toJSONString(params)).body();
+        JSONObject res = JSON.parseObject(body);
+        log.info("支付请求结果: {}", JSON.toJSONString(res, true));
+        return res;
+    }
+
+    public String requestAlipay(String orderId, BigDecimal amount, String subject,
+                                int timeout, String type, String returnUrl) {
+        JSONObject res = requestAlipayRaw(orderId, amount, subject, timeout, type, returnUrl);
+        if ("000000".equals(res.getString("ret_code"))) {
+            return res.getJSONObject("data").getString("token_id");
+        }
+        throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
+    }
+
+}

+ 48 - 0
src/main/java/com/izouma/nineth/service/OrderPayService.java

@@ -0,0 +1,48 @@
+package com.izouma.nineth.service;
+
+import com.izouma.nineth.config.GeneralProperties;
+import com.izouma.nineth.domain.Order;
+import com.izouma.nineth.enums.OrderStatus;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.GiftOrderRepo;
+import com.izouma.nineth.repo.MintOrderRepo;
+import com.izouma.nineth.repo.OrderRepo;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cache.annotation.Cacheable;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+@AllArgsConstructor
+public class OrderPayService {
+    private static String PAY_CHANNEL = "sandPay";
+
+    private final OrderRepo         orderRepo;
+    private final MintOrderRepo     mintOrderRepo;
+    private final GiftOrderRepo     giftOrderRepo;
+    private final SandPayService    sandPayService;
+    private final HMPayService      hmPayService;
+    private final GeneralProperties generalProperties;
+
+    public static void setPayChannel(String payChannel) {
+        PAY_CHANNEL = payChannel;
+    }
+
+    @Cacheable(value = "payOrder", key = "#orderId")
+    public String payOrder(Long orderId) {
+        Order order = orderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        switch (PAY_CHANNEL) {
+            case "sandPay":
+                return sandPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(),
+                        order.getName(), 180, "{\"type\":\"order\",\"id\":\"" + orderId + "\"}");
+            case "hmPay":
+                return hmPayService.requestAlipay(orderId + "", order.getTotalPrice(), order.getName(), 180,
+                        "order", generalProperties.getHost() + "/9th/orderDetail?id=" + orderId);
+        }
+        return null;
+    }
+}

+ 116 - 7
src/main/java/com/izouma/nineth/service/SandPayService.java

@@ -119,8 +119,17 @@ public class SandPayService {
         }
     }
 
-    public JSONObject requestAlipay(String orderId, BigDecimal amount, String subject, String desc,
-                                    int timeout, String extend) {
+    public String requestAlipay(String orderId, BigDecimal amount, String subject, String desc,
+                                int timeout, String extend) {
+        JSONObject res = requestAlipayRaw(orderId, amount, subject, desc, timeout, extend);
+        if ("000000".equals(res.getJSONObject("head").getString("respCode"))) {
+            return "alipays://platformapi/startapp?saId=10000007&qrcode=" + res.getJSONObject("body").getString("qrCode");
+        }
+        throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
+    }
+
+    public JSONObject requestAlipayRaw(String orderId, BigDecimal amount, String subject, String desc,
+                                       int timeout, String extend) {
         if (orderId.length() < 12) {
             for (int i = orderId.length(); i < 12; i++) {
                 orderId = "0" + orderId;
@@ -142,7 +151,7 @@ public class SandPayService {
         //body.put("limitPay", "5");                                  //限定支付方式 送1-限定不能使用贷记卡	送4-限定不能使用花呗	送5-限定不能使用贷记卡+花呗
         body.put("subject", subject);                                 //订单标题
         body.put("body", desc);                                       //订单描述
-        body.put("txnTimeOut", getTimeout(180));              //订单超时时间
+        body.put("txnTimeOut", getTimeout(timeout));                  //订单超时时间
         body.put("notifyUrl", sandPayProperties.getNotifyUrl());      //异步通知地址
         body.put("bizExtendParams", "");                              //业务扩展参数
         body.put("merchExtendParams", "");                            //商户扩展参数
@@ -239,7 +248,7 @@ public class SandPayService {
         extend.put("type", "order");
         extend.put("id", orderId);
 
-        JSONObject res = requestAlipay(orderId.toString(), order.getTotalPrice(), order.getName(), order.getName(),
+        JSONObject res = requestAlipayRaw(orderId.toString(), order.getTotalPrice(), order.getName(), order.getName(),
                 180, extend.toJSONString());
         if (res == null)
             throw new BusinessException("下单失败,请稍后再试");
@@ -296,7 +305,7 @@ public class SandPayService {
         extend.put("type", "gift");
         extend.put("id", orderId);
 
-        JSONObject res = requestAlipay(orderId.toString(), order.getGasPrice(), "转增" + order.getAssetId(), "转增" + order.getAssetId(),
+        JSONObject res = requestAlipayRaw(orderId.toString(), order.getGasPrice(), "转增" + order.getAssetId(), "转增" + order.getAssetId(),
                 180, extend.toJSONString());
         if (res == null)
             throw new BusinessException("下单失败,请稍后再试");
@@ -325,7 +334,7 @@ public class SandPayService {
         extend.put("type", "mintOrder");
         extend.put("id", orderId);
 
-        JSONObject res = requestAlipay(orderId.toString(), order.getGasPrice(), "铸造活动:" + order.getMintActivityId(),
+        JSONObject res = requestAlipayRaw(orderId.toString(), order.getGasPrice(), "铸造活动:" + order.getMintActivityId(),
                 "铸造活动:" + order.getMintActivityId(), 180, extend.toJSONString());
         if (res == null)
             throw new BusinessException("下单失败,请稍后再试");
@@ -407,7 +416,107 @@ public class SandPayService {
             try {
                 log.info("请求报文:{}", reqMap);
                 result = HttpClient.doPost("https://caspay.sandpay.com.cn/agent-main/openapi/agentpay",
-                        reqMap, 10000, 10000);
+                        reqMap, 300000, 300000);
+                result = URLDecoder.decode(result, StandardCharsets.UTF_8);
+            } catch (IOException e) {
+                log.error(e.getMessage());
+                return null;
+            }
+
+            log.info("响应报文:{}", result);
+            Map<String, String> responseMap = SDKUtil.convertResultStringToMap(result);
+
+            String retEncryptKey = responseMap.get("encryptKey");
+            String retEncryptData = responseMap.get("encryptData");
+            String retSign = responseMap.get("sign");
+
+            log.debug("retEncryptKey:[{}]", retEncryptKey);
+            log.debug("retEncryptData:[{}]", retEncryptData);
+            log.debug("retSign:[{}]", retSign);
+
+            byte[] decodeBase64KeyBytes = Base64.decodeBase64(retEncryptKey
+                    .getBytes(StandardCharsets.UTF_8));
+
+            byte[] merchantAESKeyBytes = CryptoUtil.RSADecrypt(
+                    decodeBase64KeyBytes, CertUtil.getPrivateKey(), 2048, 11,
+                    "RSA/ECB/PKCS1Padding");
+
+            byte[] decodeBase64DataBytes = Base64.decodeBase64(retEncryptData.getBytes(StandardCharsets.UTF_8));
+
+            byte[] respDataBytes = CryptoUtil.AESDecrypt(decodeBase64DataBytes,
+                    merchantAESKeyBytes, "AES", "AES/ECB/PKCS5Padding", null);
+
+            String respData = new String(respDataBytes, StandardCharsets.UTF_8);
+            log.info("retData:[" + respData + "]");
+            System.out.println("响应data数据:" + respData);
+
+            byte[] signBytes = Base64.decodeBase64(retSign.getBytes(StandardCharsets.UTF_8));
+
+            boolean isValid = CryptoUtil.verifyDigitalSign(respDataBytes, signBytes,
+                    CertUtil.getPublicKey(), "SHA1WithRSA");
+
+            if (!isValid) {
+                log.error("verify sign fail.");
+                return null;
+            }
+            log.info("verify sign success");
+            System.out.println("verify sign success");
+
+            JSONObject respJson = JSONObject.parseObject(respData);
+            return respJson;
+
+        } catch (Exception e) {
+
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+    public JSONObject queryTransfer(String tranTime, String orderId) {
+        JSONObject request = new JSONObject();
+        request.put("version", "01");          // 版本号
+        request.put("productId", "00000004");  // 产品ID
+        request.put("tranTime", tranTime);     // 查询订单的交易时间
+        request.put("orderCode", orderId);     // 要查询的订单号
+
+        String reqData = request.toJSONString();
+        log.info("请求数据:{}", reqData);
+
+        try {
+
+            String aesKey = RandomStringGenerator.getRandomStringByLength(16);
+            byte[] aesKeyBytes = aesKey.getBytes(StandardCharsets.UTF_8);
+
+            byte[] plainBytes = reqData.getBytes(StandardCharsets.UTF_8);
+            String encryptData = new String(Base64.encodeBase64(
+                    CryptoUtil.AESEncrypt(plainBytes, aesKeyBytes, "AES",
+                            "AES/ECB/PKCS5Padding", null)), StandardCharsets.UTF_8);
+
+            String sign = new String(Base64.encodeBase64(
+                    CryptoUtil.digitalSign(plainBytes, CertUtil.getPrivateKey(),
+                            "SHA1WithRSA")), StandardCharsets.UTF_8);
+
+            String encryptKey = new String(Base64.encodeBase64(
+                    CryptoUtil.RSAEncrypt(aesKeyBytes, CertUtil.getPublicKey(), 2048, 11,
+                            "RSA/ECB/PKCS1Padding")), StandardCharsets.UTF_8);
+
+
+            Map<String, String> reqMap = new HashMap<String, String>();
+            //整体报文格式
+            reqMap.put("transCode", "ODQU"); // 交易码
+            reqMap.put("accessType", "0"); // 接入类型
+            reqMap.put("merId", sandPayProperties.getMid()); // 合作商户ID	杉德系统分配,唯一标识
+            reqMap.put("plId", null);
+            reqMap.put("encryptKey", encryptKey); // 加密后的AES秘钥
+            reqMap.put("encryptData", encryptData); // 加密后的请求/应答报文
+            reqMap.put("sign", sign); // 签名
+            reqMap.put("extend", ""); // 扩展域
+
+            String result;
+            try {
+                log.info("请求报文:{}", reqMap);
+                result = HttpClient.doPost("https://caspay.sandpay.com.cn/agent-main/openapi/queryOrder",
+                        reqMap, 300000, 300000);
                 result = URLDecoder.decode(result, StandardCharsets.UTF_8);
             } catch (IOException e) {
                 log.error(e.getMessage());

+ 71 - 75
src/main/java/com/izouma/nineth/service/UserBalanceService.java

@@ -284,102 +284,98 @@ public class UserBalanceService {
     }
 
     @Async
-    public void autoWithdraw(LocalDate date) {
+    public void autoWithdraw(LocalDate date) throws ExecutionException, InterruptedException {
+        ForkJoinPool customThreadPool = new ForkJoinPool(2);
+        customThreadPool.submit(() -> {
+            autoWithdrawRecordRepo.findByDate(date).ifPresent(a -> {
+                throw new BusinessException("今日已经提现过");
+            });
 
-        autoWithdrawRecordRepo.findByDate(date).ifPresent(a -> {
-            throw new BusinessException("今日已经提现过");
-        });
+            List<UserBalance> list = userBalanceRepo.findByLockedFalseAndBalanceGreaterThanOrderByUserId(BigDecimal.ZERO);
+
+            AutoWithdrawRecord record = AutoWithdrawRecord.builder()
+                    .date(LocalDate.now())
+                    .status("pending")
+                    .progress(0)
+                    .total(list.size())
+                    .build();
+            autoWithdrawRecordRepo.saveAndFlush(record);
+
+            list.parallelStream().forEach(userBalance -> {
+                UserBankCard userBankCard = userBankCardRepo.findByUserId(userBalance.getUserId())
+                        .stream().findFirst().orElse(null);
+                if (userBankCard == null) {
+                    log.info("自动提现userId={}, amount={}, 未绑卡", userBalance.getBalance(), userBalance.getUserId());
+                    record.setProgress(record.getProgress() + 1);
+                    record.setCurrentUserId(userBalance.getUserId());
+                    autoWithdrawRecordRepo.saveAndFlush(record);
+                } else {
+                    log.info("自动提现userId={}, amount={}, name={}, bank={}",
+                            userBalance.getUserId(), userBalance.getBalance(),
+                            userBankCard.getRealName(), userBankCard.getBankNo());
 
-        List<UserBalance> list = userBalanceRepo.findByLockedFalseAndBalanceGreaterThanOrderByUserId(BigDecimal.ZERO);
-
-        AutoWithdrawRecord record = AutoWithdrawRecord.builder()
-                .date(LocalDate.now())
-                .status("pending")
-                .progress(0)
-                .total(list.size())
-                .build();
-        autoWithdrawRecordRepo.saveAndFlush(record);
-
-        for (UserBalance userBalance : list) {
-            UserBankCard userBankCard = userBankCardRepo.findByUserId(userBalance.getUserId())
-                    .stream().findFirst().orElse(null);
-            if (userBankCard == null) {
-                log.info("自动提现userId={}, amount={}, 未绑卡", userBalance.getBalance(), userBalance.getUserId());
-                record.setProgress(record.getProgress() + 1);
-                record.setCurrentUserId(userBalance.getUserId());
-                autoWithdrawRecordRepo.saveAndFlush(record);
-            } else {
-                log.info("自动提现userId={}, amount={}, name={}, bank={}",
-                        userBalance.getUserId(), userBalance.getBalance(),
-                        userBankCard.getRealName(), userBankCard.getBankNo());
-
-                String withdrawId = snowflakeIdWorker.nextId() + "";
-
-                BigDecimal amount = userBalance.getBalance();
-                userBalance.setLastBalance(userBalance.getBalance());
-                userBalance.setBalance(BigDecimal.ZERO);
-                userBalanceRepo.saveAndFlush(userBalance);
-
-                balanceRecordRepo.save(BalanceRecord.builder()
-                        .time(LocalDateTime.now())
-                        .userId(userBalance.getUserId())
-                        .amount(amount.negate())
-                        .balance(BigDecimal.ZERO)
-                        .lastBalance(userBalance.getLastBalance())
-                        .type(BalanceType.WITHDRAW)
-                        .withdrawId(withdrawId)
-                        .build());
-
-                boolean success = false;
-                String msg = null;
-                try {
-                    JSONObject res = sandPayService.transfer(withdrawId, userBankCard.getRealName(), userBankCard.getBankNo(), amount);
-                    if ("0000".equals(res.getString("respCode"))) {
-                        success = true;
-                    } else {
-                        msg = res.getString("respDesc");
-                    }
-                } catch (Exception e) {
-                    msg = e.getMessage();
-                }
+                    String withdrawId = snowflakeIdWorker.nextId() + "";
 
-                if (!success) {
+                    BigDecimal amount = userBalance.getBalance();
                     userBalance.setLastBalance(userBalance.getBalance());
-                    userBalance.setBalance(userBalance.getBalance().add(amount));
+                    userBalance.setBalance(BigDecimal.ZERO);
                     userBalanceRepo.saveAndFlush(userBalance);
 
                     balanceRecordRepo.save(BalanceRecord.builder()
                             .time(LocalDateTime.now())
                             .userId(userBalance.getUserId())
-                            .amount(amount)
-                            .balance(userBalance.getBalance())
+                            .amount(amount.negate())
+                            .balance(BigDecimal.ZERO)
                             .lastBalance(userBalance.getLastBalance())
-                            .type(BalanceType.RETURN)
+                            .type(BalanceType.WITHDRAW)
                             .withdrawId(withdrawId)
-                            .remark(msg)
                             .build());
-                }
 
-                record.setProgress(record.getProgress() + 1);
-                record.setCurrentUserId(userBalance.getUserId());
-                autoWithdrawRecordRepo.saveAndFlush(record);
+                    boolean success = false;
+                    String msg = null;
+                    try {
+                        JSONObject res = sandPayService.transfer(withdrawId, userBankCard.getRealName(), userBankCard.getBankNo(), amount);
+                        if ("0000".equals(res.getString("respCode"))) {
+                            success = true;
+                        } else {
+                            msg = res.getString("respDesc");
+                        }
+                    } catch (Exception e) {
+                        msg = e.getMessage();
+                    }
+
+                    if (!success) {
+                        userBalance.setLastBalance(userBalance.getBalance());
+                        userBalance.setBalance(userBalance.getBalance().add(amount));
+                        userBalanceRepo.saveAndFlush(userBalance);
+
+                        balanceRecordRepo.save(BalanceRecord.builder()
+                                .time(LocalDateTime.now())
+                                .userId(userBalance.getUserId())
+                                .amount(amount)
+                                .balance(userBalance.getBalance())
+                                .lastBalance(userBalance.getLastBalance())
+                                .type(BalanceType.RETURN)
+                                .withdrawId(withdrawId)
+                                .remark(msg)
+                                .build());
+                    }
 
+                    record.setProgress(record.getProgress() + 1);
+                    record.setCurrentUserId(userBalance.getUserId());
+                    autoWithdrawRecordRepo.saveAndFlush(record);
 
-                if (!success) {
-                    msg = msg == null ? "" : msg;
-                    if (msg.contains("风控") || Pattern.matches(".*\\[.*\\]", msg)) {
+                    if (!success) {
                         userBalance.setLocked(true);
                         userBalance.setLockReason(msg);
                         userBalance.setLockTime(LocalDateTime.now());
                     }
                 }
-            }
-        }
-
-        record.setStatus("finish");
-        autoWithdrawRecordRepo.saveAndFlush(record);
+            });
 
-        redisTemplate.delete("autoWithdraw::" + DateTimeUtils.format(date, "yyyyMMdd"));
+            record.setStatus("finish");
+            autoWithdrawRecordRepo.saveAndFlush(record);
+        }).get();
     }
 
     public void revert() throws ExecutionException, InterruptedException {

+ 12 - 1
src/main/java/com/izouma/nineth/service/UserService.java

@@ -145,7 +145,16 @@ public class UserService {
         if (level != null) {
             user.setLevel(level);
         }
-        return save(user);
+        user = save(user);
+        userRepo.updateAssetMinter(userId);
+        userRepo.updateAssetOwner(userId);
+        userRepo.updateCollectionMinter(userId);
+        userRepo.updateCollectionOwner(userId);
+        userRepo.updateOrderMinter(userId);
+        userRepo.updateHistoryFromUser(userId);
+        userRepo.updateHistoryToUser(userId);
+        userRepo.updateShowroomToUser(userId);
+        return user;
     }
 
     @Cacheable(value = "userList", key = "#pageQuery.hashCode()")
@@ -630,6 +639,7 @@ public class UserService {
             user.setSettleAccountId(null);
             save(user);
             userBankCardRepo.deleteByUserId(userId);
+            cacheService.clearUserMy(userId);
         } else {
             throw new BusinessException("未绑定");
         }
@@ -641,6 +651,7 @@ public class UserService {
             user.setAuthStatus(AuthStatus.NOT_AUTH);
             save(user);
             identityAuthRepo.deleteAll(identityAuthRepo.findByUserIdAndDelFalse(userId));
+            cacheService.clearUserMy(userId);
         }
     }
 

+ 23 - 0
src/main/java/com/izouma/nineth/web/HmPayController.java

@@ -0,0 +1,23 @@
+package com.izouma.nineth.web;
+
+import com.alibaba.fastjson.JSON;
+import com.izouma.nineth.service.HMPayService;
+import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/hmpay")
+@Slf4j
+@AllArgsConstructor
+public class HmPayController extends BaseController {
+    private final HMPayService hmPayService;
+
+    @GetMapping("/notify/{type}/{orderId}")
+    public String orderNotify(@PathVariable String type, @PathVariable String orderId, HttpServletRequest req) {
+        log.info("回调type={}, orderId={}, 参数={}", type, orderId, JSON.toJSONString(req.getParameterMap(), true));
+        return "respCode=000000";
+    }
+}

+ 0 - 10
src/main/java/com/izouma/nineth/web/SandPayController.java

@@ -35,16 +35,6 @@ public class SandPayController {
     private GiftOrderService  giftOrderService;
     private MintOrderService  mintOrderService;
 
-    @GetMapping(value = "/testUnion", produces = "text/html")
-    public String testUnion() {
-        JSONObject res = sandPayService.requestQuick(snowflakeIdWorker.nextId() + "", new BigDecimal("0.01"),
-                "话费充值", "话费充值", 180, "", "https://test.raex.vip/9th/home");
-        if (res.getJSONObject("head").getString("respCode").equals("000000")) {
-            return res.getJSONObject("body").getString("credential");
-        }
-        throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付。");
-    }
-
     @PostMapping("/notify")
     public Object notifyOrder(HttpServletRequest req, HttpServletResponse resp) {
         String data = req.getParameter("data");

+ 12 - 8
src/main/java/com/izouma/nineth/web/SandPayTestController.java

@@ -5,36 +5,35 @@ import com.alibaba.fastjson.JSONObject;
 import com.izouma.nineth.service.SandPayService;
 import com.izouma.nineth.utils.SnowflakeIdWorker;
 import lombok.AllArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import java.math.BigDecimal;
-import java.time.LocalDateTime;
 
 @RestController
-@RequestMapping("/sandPayTest")
+@RequestMapping("/sandPayMgr")
 @AllArgsConstructor
+@PreAuthorize("hasRole('ADMIN')")
 public class SandPayTestController {
     private final SandPayService    sandPayService;
     private final SnowflakeIdWorker snowflakeIdWorker;
 
-    @GetMapping(value = "/pay", produces = "text/html")
-    private String testpay() {
+    @GetMapping(value = "/pay")
+    private String pay() {
         JSONObject extend = new JSONObject();
         extend.put("type", "test");
         extend.put("id", 1);
-        JSONObject res = sandPayService.requestAlipay(snowflakeIdWorker.nextId() + "", new BigDecimal("0.01"),
+        JSONObject res = sandPayService.requestAlipayRaw(snowflakeIdWorker.nextId() + "", new BigDecimal("0.01"),
                 "话费充值", "话费充值", 180, extend.toJSONString());
-        String qrCode = res.getJSONObject("body").getString("qrCode");
-        return "<html><body><a style=\"font-size:28px;\" href=\"" + qrCode + "\">" + qrCode + "</a></body></html>";
+        return JSON.toJSONString(res, true);
     }
 
     @GetMapping(value = "/transfer")
     private String testTransfer(@RequestParam String name, @RequestParam String bank, @RequestParam BigDecimal amount) {
         return JSON.toJSONString(sandPayService.transfer(snowflakeIdWorker.nextId() + "", name, bank, amount), true);
-
     }
 
     @GetMapping(value = "/refund")
@@ -46,4 +45,9 @@ public class SandPayTestController {
     public String refund(@RequestParam String id) {
         return JSON.toJSONString(sandPayService.query(id), true);
     }
+
+    @GetMapping("/queryTransfer")
+    public String queryTransfer(@RequestParam String tranTime, @RequestParam String orderId) {
+        return JSON.toJSONString(sandPayService.queryTransfer(tranTime, orderId), true);
+    }
 }

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

@@ -30,6 +30,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.time.Duration;
 import java.time.LocalDate;
+import java.util.concurrent.ExecutionException;
 
 @RestController
 @RequestMapping("/userBalance")
@@ -76,7 +77,7 @@ public class UserBalanceController extends BaseController {
     }
 
     @PostMapping("/autoWithdraw")
-    public void autoWithdraw() {
+    public void autoWithdraw() throws ExecutionException, InterruptedException {
 
         LocalDate date = LocalDate.now();
         autoWithdrawRecordRepo.findByDate(date).ifPresent(a -> {

+ 6 - 0
src/main/resources/application.yaml

@@ -233,6 +233,12 @@ sandpay:
   sign-cert-pwd: 3edc#EDC
   sand-cert-path: classpath:cert/sand.cer
   notify-url: http://xiongzhu.frp.izouma.com/sandpay/notify
+hmpay:
+  mer-no: 664403000025502
+  app-private-key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJCaYSAw8c2uk4gry+/uy5thmzgdg1tPr6TRRj25AKxa13hnhjMEzp/eD8++LHxyPXg0ZXlbotZ/g0ES1XHJMkmHA4fRZ6Ki35LxlY60Z8xRwaTZXIctlaCkjhJmURNncQzyB5XMFF2M6cgy1T0yr+czoVPelVEFbAWu4cg/kQ1tAgMBAAECgYAGQwktsbDm7UZqQStFqpuakPF9zplfnOXIR1+5UIec7xohlqoTD4Q7HAynPF8EzJWo3OwAA13b2A3BBaXElafdwod7J2H9zlGJiqfmsnSTMhapVYsBbqnXGYWFS33wAm1Wx4Y9hSQxUD6AsZ+A05RiolrTTfAAGMS9E4sGhh1O6QJBANGUbGUednN4/0A0KlH3pWgLKPT+JyMeZLFGXeFLJpwWf25Xj98JcGai5t9sDqPl6xSgkEnJHdLB7LNEnmqr5X8CQQCwoaZwsVd0jnW6RU6F3SZ+BY4YS7SAhMlElqaJbBTP7DbXH/Z3cS1V696bvKup6+HlI/l0YwTDdRJIR0hl9XsTAkEAwFpPWkepQ7ZL36uBJBX9FA8aGjGhzhO5KxOAWqTU3PGxJ57qBzTsmubsqybMERWWuynbBD24R5WBH8/c7d6zFQJAShIP9TQ5Y5SWRB3qVvKtwK1dsEyXDkohCRVQE1Lyy1rYiJBL0Dzy8RQvzwlox6I2odvbMXaQudKvbwYNk0xFZwJAAxAeFweoXqDWcYl7Oa4nmgbM9LVqAMCbjzkChquXvj5q5sE9LOXiSMfbnDalNlLonbApnuTx5YCJYB0jA0ml8g==
+  app-public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQmmEgMPHNrpOIK8vv7subYZs4HYNbT6+k0UY9uQCsWtd4Z4YzBM6f3g/Pvix8cj14NGV5W6LWf4NBEtVxyTJJhwOH0Weiot+S8ZWOtGfMUcGk2VyHLZWgpI4SZlETZ3EM8geVzBRdjOnIMtU9Mq/nM6FT3pVRBWwFruHIP5ENbQIDAQAB
+  public-key: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLobxNslmsua5fnegILQSMioA5N0E5Kfg1hYLzhOuPdyJbFIImFkRF8RYt6Fp24LpDfpEEBhX8EGYIJSPpRWPZYVBzlGWOj1jS0FeF/JK+8a8ihgSxAU2JwsUySqGv+8aXIofJUus/j/KEPQZgjyVebi9J/ww75pbpGrymnAZUdwIDAQAB
+  notify-url: http://xiongzhu.frp.izouma.com/hmpay/notify
 ---
 
 spring:

+ 1 - 0
src/main/resources/cert/hmpay_app_private_key.txt

@@ -0,0 +1 @@
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJCaYSAw8c2uk4gry+/uy5thmzgdg1tPr6TRRj25AKxa13hnhjMEzp/eD8++LHxyPXg0ZXlbotZ/g0ES1XHJMkmHA4fRZ6Ki35LxlY60Z8xRwaTZXIctlaCkjhJmURNncQzyB5XMFF2M6cgy1T0yr+czoVPelVEFbAWu4cg/kQ1tAgMBAAECgYAGQwktsbDm7UZqQStFqpuakPF9zplfnOXIR1+5UIec7xohlqoTD4Q7HAynPF8EzJWo3OwAA13b2A3BBaXElafdwod7J2H9zlGJiqfmsnSTMhapVYsBbqnXGYWFS33wAm1Wx4Y9hSQxUD6AsZ+A05RiolrTTfAAGMS9E4sGhh1O6QJBANGUbGUednN4/0A0KlH3pWgLKPT+JyMeZLFGXeFLJpwWf25Xj98JcGai5t9sDqPl6xSgkEnJHdLB7LNEnmqr5X8CQQCwoaZwsVd0jnW6RU6F3SZ+BY4YS7SAhMlElqaJbBTP7DbXH/Z3cS1V696bvKup6+HlI/l0YwTDdRJIR0hl9XsTAkEAwFpPWkepQ7ZL36uBJBX9FA8aGjGhzhO5KxOAWqTU3PGxJ57qBzTsmubsqybMERWWuynbBD24R5WBH8/c7d6zFQJAShIP9TQ5Y5SWRB3qVvKtwK1dsEyXDkohCRVQE1Lyy1rYiJBL0Dzy8RQvzwlox6I2odvbMXaQudKvbwYNk0xFZwJAAxAeFweoXqDWcYl7Oa4nmgbM9LVqAMCbjzkChquXvj5q5sE9LOXiSMfbnDalNlLonbApnuTx5YCJYB0jA0ml8g==

+ 1 - 0
src/main/resources/cert/hmpay_app_public_key.txt

@@ -0,0 +1 @@
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQmmEgMPHNrpOIK8vv7subYZs4HYNbT6+k0UY9uQCsWtd4Z4YzBM6f3g/Pvix8cj14NGV5W6LWf4NBEtVxyTJJhwOH0Weiot+S8ZWOtGfMUcGk2VyHLZWgpI4SZlETZ3EM8geVzBRdjOnIMtU9Mq/nM6FT3pVRBWwFruHIP5ENbQIDAQAB

+ 1 - 0
src/main/resources/cert/hmpay_public_key.txt

@@ -0,0 +1 @@
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCLobxNslmsua5fnegILQSMioA5N0E5Kfg1hYLzhOuPdyJbFIImFkRF8RYt6Fp24LpDfpEEBhX8EGYIJSPpRWPZYVBzlGWOj1jS0FeF/JK+8a8ihgSxAU2JwsUySqGv+8aXIofJUus/j/KEPQZgjyVebi9J/ww75pbpGrymnAZUdwIDAQAB

+ 3 - 55
src/test/java/com/izouma/nineth/CommonTest.java

@@ -2,6 +2,7 @@ package com.izouma.nineth;
 
 import com.alibaba.excel.EasyExcel;
 import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.alipay.api.AlipayApiException;
 import com.alipay.api.internal.util.AlipaySignature;
@@ -640,64 +641,11 @@ public class CommonTest {
 
     @Test
     public void match() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {
-        byte[] byteKey = java.util.Base64.getDecoder().decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/应用公钥1024.txt")));
+        byte[] byteKey = java.util.Base64.getDecoder().decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/hmpay_app_public_key.txt")));
         PublicKey publicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(byteKey));
         System.out.println(publicKey);
-        byte[] bytePriv = java.util.Base64.getDecoder().decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/应用私钥1024.txt")));
+        byte[] bytePriv = java.util.Base64.getDecoder().decode(Files.readAllBytes(Path.of("/Users/drew/Downloads/hmpay_app_private_key.txt")));
         PrivateKey privKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(bytePriv));
         System.out.println(privKey);
     }
-
-    @Test
-    public void alih5() throws IOException, AlipayApiException {
-        Map<String, String> params = new HashMap<>();
-        String mer_no = "664403000025502";
-        String mer_order_no = new SnowflakeIdWorker(1, 1).nextId() + "";
-        String create_time = DateTimeUtils.format(LocalDateTime.now(), "yyyyMMddHHmmss");
-        String expire_time = DateTimeUtils.format(LocalDateTime.now().plusMinutes(3), "yyyyMMddHHmmss");
-        String create_ip = "58_213_205_43";
-        String goods_name = "话费充值";
-        String store_id = "100001";
-        String product_code = "01020002";
-        String clear_cycle = "0"; //不参与签名
-        String meta_option = "[{\"s\":\"Android\",\"n\":\"绿洲宇宙\",\"id\":\"vip.raex.nft\",\"sc\":\"wzsc://\"},{\"s\":\"IOS\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"}]"; //不参与签名
-        String jump_scheme = "sandcash://scpay";
-        String sign_type = "RSA";
-        String order_amt = "0.01";
-        String notify_url = "https://ordertest.raex.vip/sand";
-        String return_url = "https://test.raex.vip/9th/home";
-
-        params.put("mer_no", mer_no);
-        params.put("mer_order_no", mer_order_no);
-        params.put("create_time", create_time);
-        params.put("create_ip", create_ip);
-        params.put("store_id", store_id);
-        params.put("sign_type", sign_type);
-        params.put("order_amt", order_amt);
-        params.put("notify_url", notify_url);
-        params.put("return_url", return_url);
-
-        String sign = AlipaySignature.rsaSign(params, Files.readString(Path.of("/Users/drew/Downloads/应用私钥1024.txt")), "UTF-8");
-        System.out.println(sign);
-
-        String url = "https://cash.sandgate.cn/h5/?version=10&mer_no=" + mer_no +
-                "&mer_order_no=" + mer_order_no +
-                "&create_time=" + create_time +
-                "&expire_time=" + expire_time +
-                "&order_amt=" + order_amt +
-                "&notify_url=" + URLEncoder.encode(notify_url, StandardCharsets.UTF_8) +
-                "&return_url=" + URLEncoder.encode(return_url, StandardCharsets.UTF_8) +
-                "&create_ip=" + create_ip +
-                "&goods_name=" + URLEncoder.encode(goods_name, StandardCharsets.UTF_8) +
-                "&store_id=" + store_id +
-                "&product_code=" + product_code +
-                "&clear_cycle=" + clear_cycle +
-                "&pay_extra=" +
-                "&meta_option=" + URLEncoder.encode(meta_option, StandardCharsets.UTF_8) +
-                "&jump_scheme=" + jump_scheme +
-                "&sign_type=RSA&sign=" + URLEncoder.encode(sign, StandardCharsets.UTF_8) +
-                "#/hippoh5";
-        System.out.println(url);
-
-    }
 }

+ 120 - 0
src/test/java/com/izouma/nineth/HMPayTest.java

@@ -0,0 +1,120 @@
+package com.izouma.nineth;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alipay.api.AlipayApiException;
+import com.alipay.api.internal.util.AlipaySignature;
+import com.github.kevinsawicki.http.HttpRequest;
+import com.izouma.nineth.utils.DateTimeUtils;
+import com.izouma.nineth.utils.SnowflakeIdWorker;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+public class HMPayTest {
+    private String appPrivateKey;
+    private String appPublicKey;
+    private String hmPublicKey;
+
+    public HMPayTest() {
+        try {
+            this.appPrivateKey = new String(getClass().getClassLoader().getResourceAsStream("cert/hmpay_app_private_key.txt").readAllBytes()).trim();
+            this.appPublicKey = new String(getClass().getClassLoader().getResourceAsStream("cert/hmpay_app_public_key.txt").readAllBytes()).trim();
+            this.hmPublicKey = new String(getClass().getClassLoader().getResourceAsStream("cert/hmpay_public_key.txt").readAllBytes()).trim();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    private String getSign(Map<String, String> params) {
+        try {
+            Map<String, String> m = new HashMap<>(params);
+            m.remove("expire_time");
+            m.remove("goods_name");
+            m.remove("product_code");
+            m.remove("clear_cycle");
+            m.remove("jump_scheme");
+            m.remove("meta_option");
+            return AlipaySignature.rsaSign(m, appPrivateKey, "UTF-8");
+        } catch (AlipayApiException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    private void encodeParams(Map<String, String> params) {
+        List<String> arr = Arrays.asList("notify_url", "return_url", "goods_name", "meta_option", "sign", "pay_extra");
+        params.forEach((k, v) -> {
+            if (arr.contains(k)) {
+                params.put(k, URLEncoder.encode(v, StandardCharsets.UTF_8));
+            }
+        });
+    }
+
+    @Test
+    public void alih5() throws IOException, AlipayApiException {
+        Map<String, String> params = new HashMap<>();
+        params.put("version", "10");
+        params.put("mer_no", "664403000025502");
+        params.put("mer_order_no", new SnowflakeIdWorker(1, 1).nextId() + "");
+        params.put("create_time", DateTimeUtils.format(LocalDateTime.now(), "yyyyMMddHHmmss"));
+        params.put("expire_time", DateTimeUtils.format(LocalDateTime.now().plusMinutes(3), "yyyyMMddHHmmss"));
+        params.put("order_amt", "0.01");
+        params.put("notify_url", "https://testorder.raex.vip/hmpay/notify/test/123");
+        params.put("return_url", "https://test.raex.vip/9th/home");
+        params.put("create_ip", "58_213_205_43");
+        params.put("goods_name", "话费充值");
+        params.put("store_id", "100001");
+        params.put("product_code", "01020002");
+        params.put("clear_cycle", "0"); //不参与签名
+        params.put("meta_option", "[{\"s\":\"Android\",\"n\":\"绿洲宇宙\",\"id\":\"vip.raex.nft\",\"sc\":\"wzsc://\"},{\"s\":\"IOS\",\"n\":\"\",\"id\":\"\",\"sc\":\"\"}]"); //不参与签名
+        params.put("jump_scheme", "hemacash://hmpay");
+        params.put("sign_type", "RSA");
+        params.put("accsplit_info", "N");
+        params.put("sign", getSign(params));
+        encodeParams(params);
+
+//        String url = "https://cash.sandgate.cn/h5/?" +
+//                params.entrySet().stream().map(e -> e.getKey() + "=" + e.getValue())
+//                        .collect(Collectors.joining("&")) + "#/hippoh5";
+//        System.out.println(url);
+        String url = "https://cash.sandgate.cn/h5/" +
+                "?version=" + params.get("version") +
+                "&mer_no=" + params.get("mer_no") +
+                "&mer_order_no=" + params.get("mer_order_no") +
+                "&create_time=" + params.get("create_time") +
+                "&expire_time=" + params.get("expire_time") +
+                "&order_amt=" + params.get("order_amt") +
+                "&notify_url=" + params.get("notify_url") +
+                "&return_url=" + params.get("return_url") +
+                "&create_ip=" + params.get("create_ip") +
+                "&goods_name=" + params.get("goods_name") +
+                "&store_id=" + params.get("store_id") +
+                "&product_code=" + params.get("product_code") +
+                "&clear_cycle=" + params.get("clear_cycle") +
+                "&meta_option=" + params.get("meta_option") +
+                "&jump_scheme=" + params.get("jump_scheme") +
+                "&accsplit_info=" + params.get("accsplit_info") +
+                "&sign_type=" + params.get("sign_type") +
+                "&sign=" + params.get("sign") +
+                "#/hippoh5";
+        System.out.println(url);
+
+        String body = HttpRequest.post("https://cash.sandgate.cn/gateway/api")
+                .contentType("application/json")
+                .send(JSON.toJSONString(params)).body();
+        System.out.println(JSON.toJSONString(JSON.parseObject(body), true));
+    }
+
+}

+ 22 - 19
src/test/java/com/izouma/nineth/service/CollectionServiceTest.java

@@ -59,29 +59,29 @@ class CollectionServiceTest extends ApplicationTests {
     public void batchUpload() throws IOException {
         AtomicInteger num = new AtomicInteger(1);
         List<BlindBoxItem> items = new ArrayList<>();
-        String jsonStr = FileUtils.readFileToString(new File("/Users/qiufangchao/Desktop/OASISPUNK.json"), "UTF-8");
-        Arrays.stream(new File("/Users/qiufangchao/Desktop/avatar").listFiles())
+        String jsonStr = FileUtils.readFileToString(new File("/Users/qiufangchao/Desktop/mugen_mu.json"), "UTF-8");
+        Arrays.stream(new File("/Users/qiufangchao/Desktop/mugen_mu").listFiles())
                 .filter(f -> !f.getName().contains(".DS_Store"))
                 .parallel().forEach(file -> {
                     try {
-                        String name = file.getName();
-                        Pattern p = Pattern.compile("(\\d+)");
-                        Matcher matcher = p.matcher(name);
-                        matcher.find();
-                        String findname = matcher.group();
+//                        String name = file.getName();
+//                        Pattern p = Pattern.compile("(\\d+)");
+//                        Matcher matcher = p.matcher(name);
+//                        matcher.find();
+//                        String findname = matcher.group();
 
                         Collection collection = JSON.parseObject(jsonStr, Collection.class);
                         collection.setId(null);
-                        collection.setName("OASISPUNK #" + findname);
+                        collection.setName("MUGEN无限:未央宗#" + num.getAndIncrement());
                         collection.setStock(1);
                         collection.setTotal(1);
                         collection.setSale(0);
-                        collection.setMinterId(7150L);
+                        collection.setMinterId(5868950L);
                         collection.setOnShelf(false);
                         collection.setSalable(false);
 //                        String thumbPath = "https://cdn.raex.vip/thumb_image/mahjongman/" + file.getName()
 //                                .substring(0, file.getName().lastIndexOf(".")) + ".jpg";
-                        collection.setPic(Collections.singletonList(new FileObject("", "https://cdn.raex.vip/image/evo1/" + file.getName(), null, "image/png")));
+                        collection.setPic(Collections.singletonList(new FileObject("", "https://cdn.raex.vip/nft/mugen_mu/" + file.getName(), null, "image/png")));
 
                         collectionRepo.save(collection);
                         System.out.println("保存成功" + collection.getId());
@@ -102,21 +102,24 @@ class CollectionServiceTest extends ApplicationTests {
 
     @Test
     public void createBlindBox() throws IOException {
-        List<Collection> items = collectionRepo.findByNameLike("OASISPUNK.EVO #%").stream().filter(i -> {
-            int num = Integer.parseInt(i.getName().substring("OASISPUNK.EVO #".length()));
-            return num > 0 && num <= 280;
-        }).collect(Collectors.toList());
-
-        String jsonStr = FileUtils.readFileToString(new File("/Users/qiufangchao/Desktop/evo.json"), "UTF-8");
+        List<Long> arr = Arrays.asList(6862110L, 6862511L, 6862516L, 6862533L, 6862689L, 6862792L, 6862867L, 6863009L, 6863047L,
+                6863188L, 6863438L, 6863449L, 6863588L, 6863608L, 6863671L, 6863745L, 6863760L, 6863938L, 6863954L, 6864008L, 6864081L);
+        List<Collection> items = collectionRepo.findByNameLike("MUGEN无限:未央宗#%").stream().filter(i -> {
+            int num = Integer.parseInt(i.getName().substring("MUGEN无限:未央宗#".length()));
+            return num > 0 && num <= 2000 && !arr.contains(i.getId());
+        }).limit(1879).collect(Collectors.toList());
+
+        String jsonStr = FileUtils.readFileToString(new File("/Users/qiufangchao/Desktop/mugen_mu.json"), "UTF-8");
         Collection blindBox = JSON.parseObject(jsonStr, Collection.class);
         blindBox.setType(CollectionType.BLIND_BOX);
         blindBox.setId(null);
         blindBox.setOnShelf(false);
         blindBox.setSalable(false);
-        blindBox.setMinterId(7150L);
+        blindBox.setMinterId(5868950L);
         blindBox.setNoSoldOut(true);
-        blindBox.setName("OASISPUNK.EVO绿洲朋克进化版限定盲盒S3");
-        blindBox.setPic(Arrays.asList(new FileObject(null, "https://raex-meta.oss-cn-shenzhen.aliyuncs.com/image/evos3/fm.jpg", null, null)));
+        blindBox.setMaxCount(1);
+        blindBox.setName("MUGEN无限未央宗数字艺术品盲盒");
+        blindBox.setPic(Arrays.asList(new FileObject(null, "https://cdn.raex.vip/nft/2022-04-16-19-24-54WTJLmsmR.jpg", null, "image/jpeg")));
         collectionService.createBlindBox(new CreateBlindBox(blindBox, items.stream().map(i -> {
             BlindBoxItem item = new BlindBoxItem();
             item.setCollectionId(i.getId());

+ 6 - 4
src/test/java/com/izouma/nineth/service/SandPayServiceTest.java

@@ -7,9 +7,6 @@ import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
 import java.math.BigDecimal;
-import java.time.LocalDateTime;
-
-import static org.junit.jupiter.api.Assertions.*;
 
 class SandPayServiceTest extends ApplicationTests {
     @Autowired
@@ -19,7 +16,7 @@ class SandPayServiceTest extends ApplicationTests {
 
     @Test
     void requestAlipay() {
-        JSONObject jsonObject = sandPayService.requestAlipay(snowflakeIdWorker.nextId() + "", new BigDecimal("0.01"),
+        JSONObject jsonObject = sandPayService.requestAlipayRaw(snowflakeIdWorker.nextId() + "", new BigDecimal("0.01"),
                 "话费充值", "话费充值", 180, "");
         System.out.println(JSONObject.toJSONString(jsonObject, true));
     }
@@ -39,4 +36,9 @@ class SandPayServiceTest extends ApplicationTests {
             sandPayService.refund(String.format("%012d", integer), new BigDecimal("1"));
         }
     }
+
+    @Test
+    public void queryTransfer() {
+        sandPayService.queryTransfer("20220420151655", "966356799781339136");
+    }
 }