xiongzhu %!s(int64=3) %!d(string=hai) anos
pai
achega
fca3fbcd0a

+ 19 - 0
src/main/java/com/izouma/nineth/service/AirDropService.java

@@ -167,6 +167,25 @@ public class AirDropService {
         return airDropRepo.save(record);
     }
 
+    public void testCreate(AirDrop record) {
+        boolean parallel = sysConfigService.getBoolean("parallel_airdrop");
+        if (record.getTargets().isEmpty()) throw new BusinessException("空投对象不能为空");
+        if (record.getTargets().stream().mapToInt(DropTarget::getNum).sum() > 300)
+            throw new BusinessException("空投数量不能超过300");
+        if (AirDropType.coupon == record.getType()) {
+            Coupon coupon = couponRepo.findById(record.getCouponId()).orElseThrow(new BusinessException("兑换券不存在"));
+        } else {
+            Collection collection = collectionRepo.findById(record.getCollectionId())
+                    .orElseThrow(new BusinessException("藏品不存在"));
+            if (collection.isSalable()) {
+                throw new BusinessException("请先设置藏品为不可购买:" + collection.getName());
+            }
+            if (!record.isIgnoreStockCheck() && collection.getStock() < record.getTargets().stream().mapToInt(DropTarget::getNum).sum()) {
+                throw new BusinessException("藏品库存不足:" + collection.getName());
+            }
+        }
+    }
+
     @Async
     public void asyncDrop(Long collectionId, Long userId, int num, LocalDateTime time) {
         drop(collectionId, userId, num, time);

+ 185 - 47
src/main/java/com/izouma/nineth/service/MintOrderService.java

@@ -122,50 +122,6 @@ public class MintOrderService {
         return mintOrderRepo.findAll(JpaUtils.toSpecification(pageQuery, MintOrder.class), JpaUtils.toPageRequest(pageQuery));
     }
 
-    @Transactional
-    public void create(Long userId, List<Long> assetIds) {
-        User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("用户不存在"));
-        User blackHole = userRepo.findByIdAndDelFalse(Constants.BLACK_HOLE_USER_ID)
-                .orElseThrow(new BusinessException("无法铸造"));
-        if (assetIds.size() != 3) {
-            throw new BusinessException("数量不正确,请重新选择");
-        }
-        List<Asset> assets = assetRepo.findAllByIdInAndUserId(assetIds, userId);
-        assets = assets.stream()
-                .filter(asset -> asset.getName().contains("尼尔斯") && AssetStatus.NORMAL.equals(asset.getStatus()))
-                .collect(Collectors.toList());
-        if (assets.size() != 3) {
-            throw new BusinessException("有藏品不符合,请重新选择");
-        }
-
-
-        // 铸造订单
-        MintOrder order = mintOrderRepo.save(MintOrder.builder()
-                .userId(userId)
-                .phone(user.getPhone())
-                .consume(true)
-                .status(MintOrderStatus.AIR_DROP)
-                .build());
-
-        // 铸造资产
-        List<MintMaterial> materials = assets.stream().map(asset -> {
-            MintMaterial material = new MintMaterial();
-            material.setAssetId(asset.getId());
-            material.setCollectionId(asset.getCollectionId());
-            material.setName(asset.getName());
-            material.setNumber(asset.getNumber());
-            material.setPic(asset.getPic());
-            material.setCategory(asset.getCategory());
-            material.setOrderId(order.getId());
-            return material;
-        }).collect(Collectors.toList());
-
-        mintMaterialRepo.saveAll(materials);
-        // 改为转赠
-        assets.forEach(asset -> assetService.transfer(asset, asset.getPrice(), blackHole, TransferReason.GIFT, null));
-
-    }
-
     /**
      * 订单
      *
@@ -304,9 +260,9 @@ public class MintOrderService {
                             }
 //                            asset.setConsignment(false);
                         }
-                        Collection collection = collectionRepo.findById(asset.getPublicCollectionId())
-                                .orElseThrow(new BusinessException("无展示记录"));
-                        collectionRepo.delete(collection);
+                        collectionRepo.findById(asset.getPublicCollectionId())
+                                .ifPresent(collectionRepo::delete);
+
                         // 如果展厅有此藏品
                         showCollectionRepo.deleteAllByCollectionId(asset.getPublicCollectionId());
                     }
@@ -370,6 +326,188 @@ public class MintOrderService {
         }
     }
 
+    @RedisLock(value = "'mintOrderLock'+#{userId}", expire = 30, message = "操作频率过高,请稍后再试")
+    public String testCreate(User user, List<Long> assetId, Long mintActivityId, Long addressId) {
+        // 参加的活动
+        MintActivity mintActivity = mintActivityRepo.findByIdAndDelFalse(mintActivityId)
+                .orElseThrow(new BusinessException("无此铸造活动"));
+
+        if (mintActivity.isScheduleSale()) {
+            if (mintActivity.getStartTime().isAfter(LocalDateTime.now())) {
+                throw new BusinessException("当前还未开售");
+            }
+        }
+        if (!mintActivity.isOnShelf()) {
+            throw new BusinessException("活动已下架");
+        }
+
+        UserAddress userAddress = null;
+        if (addressId != null) {
+            userAddress = userAddressRepo.findById(addressId).orElseThrow(new BusinessException("地址信息不存在"));
+        }
+
+        int stock = Optional.ofNullable(mintActivityService.decreaseStock(mintActivityId, 1))
+                .map(Math::toIntExact)
+                .orElseThrow(new BusinessException("很遗憾,铸造活动已无库存"));
+        Exception ex = null;
+        try {
+            if (stock < 0) {
+                throw new BusinessException("铸造活动已无库存");
+            }
+
+            if (mintActivity.getNum() > 0) {
+                if (assetId.size() != mintActivity.getNum()) {
+                    throw new BusinessException("数量不正确,请重新选择");
+                }
+            }
+
+
+            List<Asset> assets = assetRepo.findAllByIdInAndUserId(assetId, user.getId());
+            assets.stream().forEach(asset -> {
+                if (asset.getLockTo() != null && asset.getLockTo().isAfter(LocalDateTime.now())) {
+                    throw new BusinessException("所选藏品:" + asset.getName() +
+                            (asset.getNumber() == null ? "" : ("#" + asset.getNumber())) + " 已锁定");
+                }
+            });
+//            if (assets.stream().anyMatch(a -> a.isPublicShow() || a.isConsignment())) {
+//                throw new BusinessException("请先下架所选藏品");
+//            }
+            if (assets.stream().anyMatch(a -> a.getStatus() != AssetStatus.NORMAL)) {
+                throw new BusinessException("所选藏品不符和规则,请重新选择");
+            }
+            if (!mintActivity.isAudit()) {
+                if (!mintActivityService.matchRule(new ArrayList<>(assets), mintActivity.getRule())) {
+                    throw new BusinessException("所选藏品不符和规则,请重新选择");
+                }
+            } else {
+                // 资产产品是否符合铸造活动的名称
+                assets = assets.stream()
+                        .filter(asset -> asset.getName()
+                                .contains(mintActivity.getCollectionName()) && AssetStatus.NORMAL.equals(asset.getStatus()))
+                        .collect(Collectors.toList());
+                if (mintActivity.getNum() > 0 && (assets.size() != mintActivity.getNum())) {
+                    throw new BusinessException("有藏品不符合,请重新选择");
+                }
+            }
+
+            Map<Long, Long> privilegeIds = new HashMap<>();
+            // 铸造特权
+            if (!mintActivity.isConsume()) {
+                assets.forEach(a -> {
+                    if (a.getPrivileges().stream().noneMatch(p ->
+                            "铸造".equals(p.getName())
+                                    && (!p.isOnce() || !p.isOpened()))) {
+                        throw new BusinessException(a.getName() + (a.getNumber() == null ? "" : (" #" + a.getNumber()
+                                .toString())) + " 无铸造特权或特权已使用");
+                    }
+                });
+//                assets.forEach(asset -> {
+//                    asset.getPrivileges()
+//                            .stream()
+//                            .filter(p -> !p.isOnce() || !p.isOpened())
+//                            .findFirst()
+//                            .ifPresent(p -> {
+//                                privilegeIds.put(asset.getId(), p.getId());
+//                                p.setOpened(true);
+//                                p.setOpenTime(LocalDateTime.now());
+//                                p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId());
+//                            });
+//                    assetRepo.save(asset);
+//                });
+            } else {
+                // 转让的用户
+                userRepo.findByIdAndDelFalse(Constants.BLACK_HOLE_USER_ID).orElseThrow(new BusinessException("无法铸造"));
+
+                // 消耗改为转赠
+                assets.forEach(asset -> {
+                    if (!asset.getUserId().equals(user.getId())) {
+                        throw new BusinessException("此藏品不属于你");
+                    }
+                    // 取消公开展示
+                    if (asset.isPublicShow()) {
+                        if (asset.isConsignment()) {
+                            if (asset.getPublicCollectionId() != null) {
+                                List<Order> orders = orderRepo.findByCollectionId(asset.getPublicCollectionId());
+                                if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) {
+                                    throw new BusinessException("已有订单不可取消寄售");
+                                }
+                            }
+//                            asset.setConsignment(false);
+                        }
+//                        collectionRepo.findById(asset.getPublicCollectionId())
+//                                .ifPresent(collectionRepo::delete);
+//                        // 如果展厅有此藏品
+//                        showCollectionRepo.deleteAllByCollectionId(asset.getPublicCollectionId());
+                    }
+
+                });
+
+                // 统一处理
+//                assets.forEach(asset -> {
+//                    if (asset.isPublicShow()) {
+//                        asset.setPublicShow(false);
+//                        asset.setPublicCollectionId(null);
+//                        if (asset.isConsignment()) {
+//                            asset.setConsignment(false);
+//                        }
+//                    }
+//                    asset.setStatus(AssetStatus.MINTING);
+//                    assetRepo.save(asset);
+//                });
+            }
+
+
+            // 铸造订单
+            MintOrder mintOrder = mintOrderRepo.save(MintOrder.builder()
+                    .userId(user.getId())
+                    .phone(user.getPhone())
+                    .consume(mintActivity.isConsume())
+                    .status(MintOrderStatus.NOT_PAID)
+                    .airDrop(mintActivity.isAirDrop())
+                    .gasPrice(mintActivity.getGasPrice())
+                    .mintActivityId(mintActivityId)
+                    .contactName(Optional.ofNullable(userAddress).map(UserAddress::getName).orElse(null))
+                    .contactPhone(Optional.ofNullable(userAddress).map(UserAddress::getPhone).orElse(null))
+                    .address(Optional.ofNullable(userAddress).map(UserAddress::getDetail).orElse(null))
+                    .companyId(mintActivity.getCompanyId())
+                    .build());
+
+            // 铸造资产
+            List<MintMaterial> materials = assets.stream().map(asset -> {
+                MintMaterial material = new MintMaterial();
+                material.setAssetId(asset.getId());
+                material.setCollectionId(asset.getCollectionId());
+                material.setName(asset.getName());
+                material.setPrivilegeId(privilegeIds.get(asset.getId()));
+                material.setNumber(asset.getNumber());
+                material.setPic(asset.getPic());
+                material.setCategory(asset.getCategory());
+                material.setOrderId(mintOrder.getId());
+                return material;
+            }).collect(Collectors.toList());
+
+
+            airDropService.testCreate(AirDrop.builder()
+                    .name("铸造活动[" + mintActivity.getName() + "]空投")
+                    .remark(mintOrder.getId().toString())
+                    .type(AirDropType.asset)
+                    .userIds(Collections.singletonList(mintOrder.getUserId()))
+                    .collectionId(mintActivity.getAirDropCollectionId())
+                    .targets(Collections.singletonList(new DropTarget(user.getId(), user.getPhone(), user.getNickname(), 1)))
+                    .auto(true)
+                    .companyId(mintActivity.getCompanyId())
+                    .build());
+        } catch (Exception e) {
+            ex = e;
+        }
+        mintActivityService.increaseStock(mintActivityId, 1);
+        if (ex == null) {
+            return "测试通过";
+        } else {
+            return ex.getMessage();
+        }
+    }
+
     public Object payOrderWeixin(Long id, String tradeType, String openId) throws WxPayException, EncoderException {
         MintOrder order = mintOrderRepo.findById(id).orElseThrow(new BusinessException("订单不存在"));
         if (order.getStatus() != MintOrderStatus.NOT_PAID) {

+ 3 - 1
src/main/java/com/izouma/nineth/service/TagService.java

@@ -3,11 +3,13 @@ package com.izouma.nineth.service;
 import com.izouma.nineth.domain.Tag;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.repo.TagRepo;
+import com.izouma.nineth.utils.DateTimeUtils;
 import com.izouma.nineth.utils.JpaUtils;
 import lombok.AllArgsConstructor;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 
+import java.time.LocalDate;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -38,7 +40,7 @@ public class TagService {
 
     public Tag create(String name, String remark, boolean addForExist, String addMode, String pattern, Long companyId) {
         Tag tag = tagRepo.saveAndFlush(Tag.builder()
-                .name(name)
+                .name(DateTimeUtils.format(LocalDate.now(), "MM/dd") + ": " + name)
                 .remark(remark)
                 .companyId(companyId)
                 .build());

+ 803 - 0
src/main/java/com/izouma/nineth/service/TestMintOrderService.java

@@ -0,0 +1,803 @@
+package com.izouma.nineth.service;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
+import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult;
+import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
+import com.github.binarywang.wxpay.constant.WxPayConstants;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.service.WxPayService;
+import com.huifu.adapay.core.exception.BaseAdaPayException;
+import com.huifu.adapay.model.AdapayCommon;
+import com.huifu.adapay.model.Payment;
+import com.izouma.nineth.annotations.RedisLock;
+import com.izouma.nineth.config.*;
+import com.izouma.nineth.domain.*;
+import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.*;
+import com.izouma.nineth.event.OrderNotifyEvent;
+import com.izouma.nineth.exception.BusinessException;
+import com.izouma.nineth.repo.*;
+import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.SecurityUtils;
+import com.izouma.nineth.utils.SnowflakeIdWorker;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.EncoderException;
+import org.apache.commons.codec.net.URLCodec;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.ObjectUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.rocketmq.spring.core.RocketMQTemplate;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.core.env.Environment;
+import org.springframework.data.domain.Page;
+import org.springframework.data.redis.core.BoundSetOperations;
+import org.springframework.data.redis.core.BoundValueOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import javax.transaction.Transactional;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class TestMintOrderService {
+
+    private final MintOrderRepo                 mintOrderRepo;
+    private final UserRepo                      userRepo;
+    private final AssetService                  assetService;
+    private final AssetRepo                     assetRepo;
+    private final MintActivityRepo              mintActivityRepo;
+    private final UserAddressRepo               userAddressRepo;
+    private final GeneralProperties             generalProperties;
+    private final Environment                   env;
+    private final AdapayProperties              adapayProperties;
+    private final SnowflakeIdWorker             snowflakeIdWorker;
+    private final WxPayProperties               wxPayProperties;
+    private final WxPayService                  wxPayService;
+    private final MintMaterialRepo              mintMaterialRepo;
+    private final MintActivityService           mintActivityService;
+    private final RedisTemplate<String, Object> redisTemplate;
+    private final RocketMQTemplate              rocketMQTemplate;
+    private final CollectionRepo                collectionRepo;
+    private final OrderRepo                     orderRepo;
+    private final ShowCollectionRepo            showCollectionRepo;
+    private final AirDropService                airDropService;
+    private final OrderPayService               orderPayService;
+
+    public TestMintOrderService(MintOrderRepo mintOrderRepo,
+                                UserRepo userRepo,
+                                AssetService assetService,
+                                AssetRepo assetRepo,
+                                MintActivityRepo mintActivityRepo,
+                                UserAddressRepo userAddressRepo,
+                                GeneralProperties generalProperties,
+                                Environment env,
+                                AdapayProperties adapayProperties,
+                                SnowflakeIdWorker snowflakeIdWorker,
+                                WxPayProperties wxPayProperties,
+                                WxPayService wxPayService,
+                                MintMaterialRepo mintMaterialRepo,
+                                MintActivityService mintActivityService,
+                                RedisTemplate<String, Object> redisTemplate,
+                                RocketMQTemplate rocketMQTemplate,
+                                CollectionRepo collectionRepo,
+                                OrderRepo orderRepo,
+                                ShowCollectionRepo showCollectionRepo,
+                                AirDropService airDropService,
+                                @Lazy OrderPayService orderPayService) {
+        this.mintOrderRepo = mintOrderRepo;
+        this.userRepo = userRepo;
+        this.assetService = assetService;
+        this.assetRepo = assetRepo;
+        this.mintActivityRepo = mintActivityRepo;
+        this.userAddressRepo = userAddressRepo;
+        this.generalProperties = generalProperties;
+        this.env = env;
+        this.adapayProperties = adapayProperties;
+        this.snowflakeIdWorker = snowflakeIdWorker;
+        this.wxPayProperties = wxPayProperties;
+        this.wxPayService = wxPayService;
+        this.mintMaterialRepo = mintMaterialRepo;
+        this.mintActivityService = mintActivityService;
+        this.redisTemplate = redisTemplate;
+        this.rocketMQTemplate = rocketMQTemplate;
+        this.collectionRepo = collectionRepo;
+        this.orderRepo = orderRepo;
+        this.showCollectionRepo = showCollectionRepo;
+        this.airDropService = airDropService;
+        this.orderPayService = orderPayService;
+    }
+
+    public Page<MintOrder> all(PageQuery pageQuery) {
+        return mintOrderRepo.findAll(JpaUtils.toSpecification(pageQuery, MintOrder.class), JpaUtils.toPageRequest(pageQuery));
+    }
+
+    /**
+     * 订单
+     *
+     * @param id 编号
+     */
+    public void finish(Long id) {
+        MintOrder mintOrder = mintOrderRepo.findById(id).orElseThrow(new BusinessException("铸造订单不存在"));
+        mintOrder.setStatus(MintOrderStatus.FINISH);
+        mintOrderRepo.save(mintOrder);
+    }
+
+    /**
+     * 发货
+     *
+     * @param id        编号
+     * @param courierId 快递单号
+     */
+    public void dispatch(Long id, String courierId) {
+        MintOrder mintOrder = mintOrderRepo.findById(id).orElseThrow(new BusinessException("铸造订单不存在"));
+        mintOrder.setStatus(MintOrderStatus.RECEIVE);
+        mintOrder.setCourierId(courierId);
+        mintOrderRepo.save(mintOrder);
+    }
+
+    /**
+     * @param user           用户
+     * @param assetId        资产
+     * @param mintActivityId 铸造活动
+     * @param addressId      地址
+     */
+//    @Transactional
+    @RedisLock(value = "'mintOrderLock'+#{userId}", expire = 30, message = "操作频率过高,请稍后再试")
+    public MintOrder create(User user, List<Long> assetId, Long mintActivityId, Long addressId) {
+        // 参加的活动
+        MintActivity mintActivity = mintActivityRepo.findByIdAndDelFalse(mintActivityId)
+                .orElseThrow(new BusinessException("无此铸造活动"));
+
+        if (mintActivity.isScheduleSale()) {
+            if (mintActivity.getStartTime().isAfter(LocalDateTime.now())) {
+                throw new BusinessException("当前还未开售");
+            }
+        }
+        if (!mintActivity.isOnShelf()) {
+            throw new BusinessException("活动已下架");
+        }
+
+        UserAddress userAddress = null;
+        if (addressId != null) {
+            userAddress = userAddressRepo.findById(addressId).orElseThrow(new BusinessException("地址信息不存在"));
+        }
+
+        int stock = Optional.ofNullable(mintActivityService.decreaseStock(mintActivityId, 1))
+                .map(Math::toIntExact)
+                .orElseThrow(new BusinessException("很遗憾,铸造活动已无库存"));
+        try {
+            if (stock < 0) {
+                throw new BusinessException("铸造活动已无库存");
+            }
+
+            if (mintActivity.getNum() > 0) {
+                if (assetId.size() != mintActivity.getNum()) {
+                    throw new BusinessException("数量不正确,请重新选择");
+                }
+            }
+
+
+            List<Asset> assets = assetRepo.findAllByIdInAndUserId(assetId, user.getId());
+            assets.stream().forEach(asset -> {
+                if (asset.getLockTo() != null && asset.getLockTo().isAfter(LocalDateTime.now())) {
+                    throw new BusinessException("所选藏品:" + asset.getName() +
+                            (asset.getNumber() == null ? "" : ("#" + asset.getNumber())) + " 已锁定");
+                }
+            });
+//            if (assets.stream().anyMatch(a -> a.isPublicShow() || a.isConsignment())) {
+//                throw new BusinessException("请先下架所选藏品");
+//            }
+            if (assets.stream().anyMatch(a -> a.getStatus() != AssetStatus.NORMAL)) {
+                throw new BusinessException("所选藏品不符和规则,请重新选择");
+            }
+            if (!mintActivity.isAudit()) {
+                if (!mintActivityService.matchRule(new ArrayList<>(assets), mintActivity.getRule())) {
+                    throw new BusinessException("所选藏品不符和规则,请重新选择");
+                }
+            } else {
+                // 资产产品是否符合铸造活动的名称
+                assets = assets.stream()
+                        .filter(asset -> asset.getName()
+                                .contains(mintActivity.getCollectionName()) && AssetStatus.NORMAL.equals(asset.getStatus()))
+                        .collect(Collectors.toList());
+                if (mintActivity.getNum() > 0 && (assets.size() != mintActivity.getNum())) {
+                    throw new BusinessException("有藏品不符合,请重新选择");
+                }
+            }
+
+            Map<Long, Long> privilegeIds = new HashMap<>();
+            // 铸造特权
+            if (!mintActivity.isConsume()) {
+                assets.forEach(a -> {
+                    if (a.getPrivileges().stream().noneMatch(p ->
+                            "铸造".equals(p.getName())
+                                    && (!p.isOnce() || !p.isOpened()))) {
+                        throw new BusinessException(a.getName() + (a.getNumber() == null ? "" : (" #" + a.getNumber()
+                                .toString())) + " 无铸造特权或特权已使用");
+                    }
+                });
+                assets.forEach(asset -> {
+                    asset.getPrivileges()
+                            .stream()
+                            .filter(p -> !p.isOnce() || !p.isOpened())
+                            .findFirst()
+                            .ifPresent(p -> {
+                                privilegeIds.put(asset.getId(), p.getId());
+                                p.setOpened(true);
+                                p.setOpenTime(LocalDateTime.now());
+                                p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId());
+                            });
+                    assetRepo.save(asset);
+                });
+            } else {
+                // 转让的用户
+                userRepo.findByIdAndDelFalse(Constants.BLACK_HOLE_USER_ID).orElseThrow(new BusinessException("无法铸造"));
+
+                // 消耗改为转赠
+                assets.forEach(asset -> {
+                    if (!asset.getUserId().equals(user.getId())) {
+                        throw new BusinessException("此藏品不属于你");
+                    }
+                    // 取消公开展示
+                    if (asset.isPublicShow()) {
+                        if (asset.isConsignment()) {
+                            if (asset.getPublicCollectionId() != null) {
+                                List<Order> orders = orderRepo.findByCollectionId(asset.getPublicCollectionId());
+                                if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) {
+                                    throw new BusinessException("已有订单不可取消寄售");
+                                }
+                            }
+//                            asset.setConsignment(false);
+                        }
+                        collectionRepo.findById(asset.getPublicCollectionId())
+                                .ifPresent(collectionRepo::delete);
+
+                        // 如果展厅有此藏品
+                        showCollectionRepo.deleteAllByCollectionId(asset.getPublicCollectionId());
+                    }
+
+                });
+
+                // 统一处理
+                assets.forEach(asset -> {
+                    if (asset.isPublicShow()) {
+                        asset.setPublicShow(false);
+                        asset.setPublicCollectionId(null);
+                        if (asset.isConsignment()) {
+                            asset.setConsignment(false);
+                        }
+                    }
+                    asset.setStatus(AssetStatus.MINTING);
+                    assetRepo.save(asset);
+                });
+            }
+
+
+            // 铸造订单
+            MintOrder mintOrder = mintOrderRepo.save(MintOrder.builder()
+                    .userId(user.getId())
+                    .phone(user.getPhone())
+                    .consume(mintActivity.isConsume())
+                    .status(MintOrderStatus.NOT_PAID)
+                    .airDrop(mintActivity.isAirDrop())
+                    .gasPrice(mintActivity.getGasPrice())
+                    .mintActivityId(mintActivityId)
+                    .contactName(Optional.ofNullable(userAddress).map(UserAddress::getName).orElse(null))
+                    .contactPhone(Optional.ofNullable(userAddress).map(UserAddress::getPhone).orElse(null))
+                    .address(Optional.ofNullable(userAddress).map(UserAddress::getDetail).orElse(null))
+                    .companyId(mintActivity.getCompanyId())
+                    .build());
+
+            // 铸造资产
+            List<MintMaterial> materials = assets.stream().map(asset -> {
+                MintMaterial material = new MintMaterial();
+                material.setAssetId(asset.getId());
+                material.setCollectionId(asset.getCollectionId());
+                material.setName(asset.getName());
+                material.setPrivilegeId(privilegeIds.get(asset.getId()));
+                material.setNumber(asset.getNumber());
+                material.setPic(asset.getPic());
+                material.setCategory(asset.getCategory());
+                material.setOrderId(mintOrder.getId());
+                return material;
+            }).collect(Collectors.toList());
+
+            mintMaterialRepo.saveAll(materials);
+
+            if (mintOrder.getGasPrice().compareTo(BigDecimal.ZERO) == 0) {
+                this.mintNotify(mintOrder.getId(), PayMethod.WEIXIN, null);
+            }
+            return mintOrder;
+        } catch (Exception e) {
+            // 错了加库存
+            mintActivityService.increaseStock(mintActivityId, 1);
+            throw e;
+        }
+    }
+
+    @RedisLock(value = "'mintOrderLock'+#{userId}", expire = 30, message = "操作频率过高,请稍后再试")
+    public String testCreate(User user, List<Long> assetId, Long mintActivityId, Long addressId) {
+        // 参加的活动
+        MintActivity mintActivity = mintActivityRepo.findByIdAndDelFalse(mintActivityId)
+                .orElseThrow(new BusinessException("无此铸造活动"));
+
+        if (mintActivity.isScheduleSale()) {
+            if (mintActivity.getStartTime().isAfter(LocalDateTime.now())) {
+                throw new BusinessException("当前还未开售");
+            }
+        }
+        if (!mintActivity.isOnShelf()) {
+            throw new BusinessException("活动已下架");
+        }
+
+        UserAddress userAddress = null;
+        if (addressId != null) {
+            userAddress = userAddressRepo.findById(addressId).orElseThrow(new BusinessException("地址信息不存在"));
+        }
+
+        int stock = Optional.ofNullable(mintActivityService.decreaseStock(mintActivityId, 1))
+                .map(Math::toIntExact)
+                .orElseThrow(new BusinessException("很遗憾,铸造活动已无库存"));
+        Exception ex = null;
+        try {
+            if (stock < 0) {
+                throw new BusinessException("铸造活动已无库存");
+            }
+
+            if (mintActivity.getNum() > 0) {
+                if (assetId.size() != mintActivity.getNum()) {
+                    throw new BusinessException("数量不正确,请重新选择");
+                }
+            }
+
+
+            List<Asset> assets = assetRepo.findAllByIdInAndUserId(assetId, user.getId());
+            assets.stream().forEach(asset -> {
+                if (asset.getLockTo() != null && asset.getLockTo().isAfter(LocalDateTime.now())) {
+                    throw new BusinessException("所选藏品:" + asset.getName() +
+                            (asset.getNumber() == null ? "" : ("#" + asset.getNumber())) + " 已锁定");
+                }
+            });
+//            if (assets.stream().anyMatch(a -> a.isPublicShow() || a.isConsignment())) {
+//                throw new BusinessException("请先下架所选藏品");
+//            }
+            if (assets.stream().anyMatch(a -> a.getStatus() != AssetStatus.NORMAL)) {
+                throw new BusinessException("所选藏品不符和规则,请重新选择");
+            }
+            if (!mintActivity.isAudit()) {
+                if (!mintActivityService.matchRule(new ArrayList<>(assets), mintActivity.getRule())) {
+                    throw new BusinessException("所选藏品不符和规则,请重新选择");
+                }
+            } else {
+                // 资产产品是否符合铸造活动的名称
+                assets = assets.stream()
+                        .filter(asset -> asset.getName()
+                                .contains(mintActivity.getCollectionName()) && AssetStatus.NORMAL.equals(asset.getStatus()))
+                        .collect(Collectors.toList());
+                if (mintActivity.getNum() > 0 && (assets.size() != mintActivity.getNum())) {
+                    throw new BusinessException("有藏品不符合,请重新选择");
+                }
+            }
+
+            Map<Long, Long> privilegeIds = new HashMap<>();
+            // 铸造特权
+            if (!mintActivity.isConsume()) {
+                assets.forEach(a -> {
+                    if (a.getPrivileges().stream().noneMatch(p ->
+                            "铸造".equals(p.getName())
+                                    && (!p.isOnce() || !p.isOpened()))) {
+                        throw new BusinessException(a.getName() + (a.getNumber() == null ? "" : (" #" + a.getNumber()
+                                .toString())) + " 无铸造特权或特权已使用");
+                    }
+                });
+//                assets.forEach(asset -> {
+//                    asset.getPrivileges()
+//                            .stream()
+//                            .filter(p -> !p.isOnce() || !p.isOpened())
+//                            .findFirst()
+//                            .ifPresent(p -> {
+//                                privilegeIds.put(asset.getId(), p.getId());
+//                                p.setOpened(true);
+//                                p.setOpenTime(LocalDateTime.now());
+//                                p.setOpenedBy(SecurityUtils.getAuthenticatedUser().getId());
+//                            });
+//                    assetRepo.save(asset);
+//                });
+            } else {
+                // 转让的用户
+                userRepo.findByIdAndDelFalse(Constants.BLACK_HOLE_USER_ID).orElseThrow(new BusinessException("无法铸造"));
+
+                // 消耗改为转赠
+                assets.forEach(asset -> {
+                    if (!asset.getUserId().equals(user.getId())) {
+                        throw new BusinessException("此藏品不属于你");
+                    }
+                    // 取消公开展示
+                    if (asset.isPublicShow()) {
+                        if (asset.isConsignment()) {
+                            if (asset.getPublicCollectionId() != null) {
+                                List<Order> orders = orderRepo.findByCollectionId(asset.getPublicCollectionId());
+                                if (orders.stream().anyMatch(o -> o.getStatus() != OrderStatus.CANCELLED)) {
+                                    throw new BusinessException("已有订单不可取消寄售");
+                                }
+                            }
+//                            asset.setConsignment(false);
+                        }
+//                        collectionRepo.findById(asset.getPublicCollectionId())
+//                                .ifPresent(collectionRepo::delete);
+//                        // 如果展厅有此藏品
+//                        showCollectionRepo.deleteAllByCollectionId(asset.getPublicCollectionId());
+                    }
+
+                });
+
+                // 统一处理
+//                assets.forEach(asset -> {
+//                    if (asset.isPublicShow()) {
+//                        asset.setPublicShow(false);
+//                        asset.setPublicCollectionId(null);
+//                        if (asset.isConsignment()) {
+//                            asset.setConsignment(false);
+//                        }
+//                    }
+//                    asset.setStatus(AssetStatus.MINTING);
+//                    assetRepo.save(asset);
+//                });
+            }
+
+
+            // 铸造订单
+            MintOrder mintOrder = mintOrderRepo.save(MintOrder.builder()
+                    .userId(user.getId())
+                    .phone(user.getPhone())
+                    .consume(mintActivity.isConsume())
+                    .status(MintOrderStatus.NOT_PAID)
+                    .airDrop(mintActivity.isAirDrop())
+                    .gasPrice(mintActivity.getGasPrice())
+                    .mintActivityId(mintActivityId)
+                    .contactName(Optional.ofNullable(userAddress).map(UserAddress::getName).orElse(null))
+                    .contactPhone(Optional.ofNullable(userAddress).map(UserAddress::getPhone).orElse(null))
+                    .address(Optional.ofNullable(userAddress).map(UserAddress::getDetail).orElse(null))
+                    .companyId(mintActivity.getCompanyId())
+                    .build());
+
+            // 铸造资产
+            List<MintMaterial> materials = assets.stream().map(asset -> {
+                MintMaterial material = new MintMaterial();
+                material.setAssetId(asset.getId());
+                material.setCollectionId(asset.getCollectionId());
+                material.setName(asset.getName());
+                material.setPrivilegeId(privilegeIds.get(asset.getId()));
+                material.setNumber(asset.getNumber());
+                material.setPic(asset.getPic());
+                material.setCategory(asset.getCategory());
+                material.setOrderId(mintOrder.getId());
+                return material;
+            }).collect(Collectors.toList());
+
+            mintMaterialRepo.saveAll(materials);
+
+            if (mintOrder.getGasPrice().compareTo(BigDecimal.ZERO) == 0) {
+                this.mintNotify(mintOrder.getId(), PayMethod.WEIXIN, null);
+            }
+        } catch (Exception e) {
+            ex = e;
+            // 错了加库存
+            mintActivityService.increaseStock(mintActivityId, 1);
+        }
+        if (ex == null) {
+            mintActivityService.increaseStock(mintActivityId, 1);
+            return "测试通过";
+        } else {
+            return ex.getMessage();
+        }
+    }
+
+    public Object payOrderWeixin(Long id, String tradeType, String openId) throws WxPayException, EncoderException {
+        MintOrder order = mintOrderRepo.findById(id).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getStatus() != MintOrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+
+        WxPayUnifiedOrderRequest request = new WxPayUnifiedOrderRequest();
+        request.setBody("铸造GAS费");
+        request.setOutTradeNo(String.valueOf(new SnowflakeIdWorker(1, 1).nextId()));
+        request.setTotalFee(order.getGasPrice().multiply(BigDecimal.valueOf(100)).intValue());
+        if (Arrays.stream(env.getActiveProfiles()).noneMatch(s -> s.equals("prod"))) {
+            // 测试环境设为1分
+//                    request.setTotalFee(1);
+        }
+        request.setSpbillCreateIp("180.102.110.170");
+        request.setNotifyUrl(wxPayProperties.getNotifyUrl());
+        request.setTradeType(tradeType);
+        request.setOpenid(openId);
+        request.setSignType("MD5");
+        JSONObject body = new JSONObject();
+        body.put("action", "payMintOrder");
+        body.put("userId", order.getUserId());
+        body.put("orderId", order.getId());
+        request.setAttach(body.toJSONString());
+
+        if (WxPayConstants.TradeType.MWEB.equals(tradeType)) {
+            WxPayMwebOrderResult result = wxPayService.createOrder(request);
+            return result.getMwebUrl() + "&redirect_url=" + new URLCodec().encode(wxPayProperties.getReturnUrl());
+        } else if (WxPayConstants.TradeType.JSAPI.equals(tradeType)) {
+            return wxPayService.<WxPayMpOrderResult>createOrder(request);
+        }
+        throw new BusinessException("不支持此付款方式");
+    }
+
+    public Object payAdapay(Long id, String payChannel, String openId) throws BaseAdaPayException {
+        List<String> aliChannels = Arrays.asList("alipay", "alipay_qr", "alipay_wap");
+        List<String> wxChannels = Arrays.asList("wx_pub", "wx_lite");
+        if (!aliChannels.contains(payChannel) && !wxChannels.contains(payChannel)) {
+            throw new BusinessException("不支持此渠道");
+        }
+        MintOrder order = mintOrderRepo.findById(id).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getStatus() != MintOrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+
+        Map<String, Object> paymentParams = new HashMap<>();
+        paymentParams.put("order_no", String.valueOf(snowflakeIdWorker.nextId()));
+        paymentParams.put("pay_amt", order.getGasPrice().setScale(2, RoundingMode.HALF_UP).toPlainString());
+        paymentParams.put("app_id", adapayProperties.getAppId());
+        paymentParams.put("pay_channel", payChannel);
+        paymentParams.put("goods_title", "铸造GAS费");
+        paymentParams.put("goods_desc", "铸造GAS费");
+        paymentParams.put("time_expire", DateTimeFormatter.ofPattern("yyyyMMddHHmmss")
+                .format(LocalDateTime.now().plusMinutes(5)));
+        paymentParams.put("notify_url", adapayProperties.getNotifyUrl() + "/mintOrder/" + order.getId());
+
+        Map<String, Object> expend = new HashMap<>();
+        paymentParams.put("expend", expend);
+        if ("wx_pub".equals(payChannel)) {
+            if (StringUtils.isBlank(openId)) {
+                throw new BusinessException("缺少openId");
+            }
+            expend.put("open_id", openId);
+            expend.put("limit_pay", "1");
+        }
+
+        Map<String, Object> response;
+        if ("wx_lite".equals(payChannel)) {
+            paymentParams.put("adapay_func_code", "wxpay.createOrder");
+            paymentParams.put("callback_url", generalProperties.getHost() + "/9th/orders");
+            response = AdapayCommon.requestAdapayUits(paymentParams);
+            log.info("createOrderResponse {}", JSON.toJSONString(response, SerializerFeature.PrettyFormat));
+        } else {
+            response = Payment.create(paymentParams);
+            log.info("createOrderResponse {}", JSON.toJSONString(response, SerializerFeature.PrettyFormat));
+            AdapayService.checkSuccess(response);
+
+            // adapay 同步
+            BoundSetOperations<String, Object> ops = redisTemplate.boundSetOps(RedisKeys.ACTIVITY_PAY_RECORD + order.getId());
+            ops.add(MapUtils.getString(response, "id"));
+            ops.expire(7, TimeUnit.DAYS);
+        }
+
+        switch (payChannel) {
+            case "alipay_wap":
+            case "alipay":
+                return MapUtils.getString(MapUtils.getMap(response, "expend"), "pay_info");
+            case "alipay_qr":
+                return MapUtils.getString(MapUtils.getMap(response, "expend"), "qrcode_url");
+            case "wx_pub":
+                JSONObject payParams = JSON.parseObject(MapUtils.getString(MapUtils.getMap(response, "expend"), "pay_info"));
+                payParams.put("timestamp", payParams.get("timeStamp"));
+                payParams.remove("timeStamp");
+                return payParams;
+            default:
+                return MapUtils.getMap(response, "expend");
+        }
+    }
+
+    @Transactional
+    public void mintNotify(Long orderId, PayMethod payMethod, String transactionId) {
+        log.info("铸造订单回调 orderId: {}, payMethod: {}, transactionId: {}", orderId, payMethod, transactionId);
+
+        if (!getOrderLock(orderId)) {
+            log.info("铸造订单回调失败 orderId: {} redis锁定, 重新发送到队列", orderId);
+            rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                    new OrderNotifyEvent(orderId, payMethod, transactionId, System.currentTimeMillis(),
+                            OrderNotifyEvent.TYPE_MINT_ORDER));
+            return;
+        }
+
+        try {
+            MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+            if (order.getStatus() == MintOrderStatus.NOT_PAID) {
+                MintActivity activity = mintActivityRepo.findById(order.getMintActivityId())
+                        .orElseThrow(new BusinessException("无活动"));
+                //活动是否需要审核
+                if (activity.isAudit()) {
+                    order.setStatus(MintOrderStatus.PENDING);
+                    order.setTransactionId(transactionId);
+                    order.setPayMethod(payMethod);
+                    order.setPayAt(LocalDateTime.now());
+                    mintOrderRepo.save(order);
+                } else {
+                    this.notify(order, payMethod, transactionId, true);
+                }
+            }
+        } catch (Exception e) {
+            log.info("铸造订单回调出错 orderId={}", orderId, e);
+        }
+
+        releaseOrderLock(orderId);
+    }
+
+    public void orderAudit(Long orderId, boolean pass) {
+        MintOrder order = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (!MintOrderStatus.PENDING.equals(order.getStatus())) {
+            throw new BusinessException("状态错误");
+        }
+
+        if (pass) {
+            this.notify(order, null, null, false);
+            return;
+        }
+        this.cancel(order, true);
+    }
+
+
+    @Transactional
+    public void notify(MintOrder mintOrder, PayMethod payMethod, String transactionId, boolean saveTransactionId) {
+        Long orderId = mintOrder.getId();
+
+        try {
+//            MintOrder mintOrder = mintOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+            List<MintMaterial> materials = mintMaterialRepo.findAllByOrderIdAndDelFalse(orderId);
+            List<Asset> assets = assetRepo.findAllById(materials
+                    .stream()
+                    .map(MintMaterial::getAssetId)
+                    .collect(Collectors.toList()));
+
+            if (saveTransactionId) {
+                mintOrder.setPayMethod(payMethod);
+                mintOrder.setTransactionId(transactionId);
+                mintOrder.setPayAt(LocalDateTime.now());
+            }
+
+            if (mintOrder.isAirDrop()) {
+                mintOrder.setStatus(MintOrderStatus.AIR_DROP);
+                MintActivity mintActivity = mintActivityRepo.findById(mintOrder.getMintActivityId()).orElse(null);
+                if (ObjectUtils.isNotEmpty(mintActivity) && mintActivity.isAutoDrop()) {
+                    User user = userRepo.findById(mintOrder.getUserId()).orElseThrow(new BusinessException("无用户"));
+                    airDropService.create(AirDrop.builder()
+                            .name("铸造活动[" + mintActivity.getName() + "]空投")
+                            .remark(mintOrder.getId().toString())
+                            .type(AirDropType.asset)
+                            .userIds(Collections.singletonList(mintOrder.getUserId()))
+                            .collectionId(mintActivity.getAirDropCollectionId())
+                            .targets(Collections.singletonList(new DropTarget(user.getId(), user.getPhone(), user.getNickname(), 1)))
+                            .auto(true)
+                            .companyId(mintActivity.getCompanyId())
+                            .build());
+                    mintOrder.setStatus(MintOrderStatus.FINISH);
+                    mintOrderRepo.save(mintOrder);
+                }
+            } else {
+                mintOrder.setStatus(MintOrderStatus.DELIVERY);
+            }
+
+            if (mintOrder.isConsume()) {
+                User newOwner = userRepo.findByIdAndDelFalse(Constants.BLACK_HOLE_USER_ID)
+                        .orElseThrow(new BusinessException("无法铸造"));
+                assets.forEach(asset -> assetService.transfer(asset, asset.getPrice(), newOwner, TransferReason.GIFT, null));
+            }
+            mintOrderRepo.save(mintOrder);
+
+        } catch (Exception e) {
+            if (e instanceof BusinessException) {
+                log.error("铸造订单回调出错 orderId: {} {}", orderId, e.getMessage());
+            } else {
+                log.error("铸造订单回调出错 orderId: " + orderId, e);
+            }
+        }
+    }
+
+    public void cancel(MintOrder order, boolean refund) {
+        if (!getOrderLock(order.getId())) {
+            log.error("订单取消失败 {}, redis锁了", order.getId());
+            return;
+        }
+
+        try {
+            // 审核中或未支付订单可以取消
+            if (!(MintOrderStatus.PENDING == order.getStatus() || MintOrderStatus.NOT_PAID == order.getStatus() || refund)) {
+                throw new BusinessException("此状态无法取消");
+            }
+
+            List<MintMaterial> materials = mintMaterialRepo.findAllByOrderIdAndDelFalse(order.getId());
+            List<Asset> assets = assetRepo.findAllById(materials.stream()
+                    .map(MintMaterial::getAssetId)
+                    .collect(Collectors.toList()));
+
+            if (order.isConsume()) {
+                assets.forEach(asset -> {
+                    asset.setStatus(AssetStatus.NORMAL);
+                    assetRepo.save(asset);
+                });
+            } else {
+                Map<Long, Long> privilegeIds = materials.stream()
+                        .collect(Collectors.toMap(MintMaterial::getAssetId, MintMaterial::getPrivilegeId));
+                assets.forEach(asset -> {
+                    asset.getPrivileges()
+                            .stream()
+                            .filter(p -> p.getId().equals(privilegeIds.get(asset.getId())))
+                            .forEach(p -> {
+                                p.setOpened(false);
+                                p.setOpenTime(null);
+                                p.setOpenedBy(null);
+                            });
+                    assetRepo.save(asset);
+                });
+            }
+
+            log.info("set normal mintOrder {}", order.getId());
+
+            order.setStatus(MintOrderStatus.CANCELLED);
+            order.setCancelTime(LocalDateTime.now());
+            mintOrderRepo.save(order);
+
+            // 加库存
+            mintActivityService.increaseStock(order.getMintActivityId(), 1);
+            log.info("取消订单{}", order.getId());
+
+            if (order.getPayMethod() != null && StringUtils.isNotBlank(order.getTransactionId())) {
+                log.info("退款铸造订单{}", order.getId());
+                PayMethod payMethod = order.getPayMethod();
+                if (PayMethod.ALIPAY == payMethod) {
+                    if (StringUtils.length(order.getTransactionId()) == 28) {
+                        payMethod = PayMethod.HMPAY;
+                    } else if (StringUtils.length(order.getTransactionId()) == 30) {
+                        payMethod = PayMethod.SANDPAY;
+                    }
+                }
+                try {
+                    switch (payMethod) {
+                        case HMPAY:
+                            orderPayService.refund(order.getId().toString(), order.getTransactionId(),
+                                    order.getGasPrice(), Constants.PayChannel.HM);
+                            log.info("退款成功");
+                            break;
+                        case SANDPAY:
+                            orderPayService.refund(order.getId().toString(), order.getTransactionId(),
+                                    order.getGasPrice(), Constants.PayChannel.SAND);
+                            log.info("退款成功");
+                            break;
+                        case PAYEASE:
+                            orderPayService.refund(order.getTransactionId(), order.getTransactionId(),
+                                    order.getGasPrice(), Constants.PayChannel.PE);
+                    }
+                } catch (Exception e) {
+                    log.error("铸造订单退款失败 {} ", order.getId(), e);
+                }
+            }
+        } catch (Exception e) {
+            log.error("订单取消错误 orderId: " + order.getId(), e);
+        }
+        releaseOrderLock(order.getId());
+    }
+
+    public boolean getOrderLock(Long orderId) {
+        BoundValueOperations<String, Object> ops = redisTemplate.boundValueOps(RedisKeys.MINT_ORDER_LOCK + orderId);
+        Boolean flag = ops.setIfAbsent(1, 1, TimeUnit.DAYS);
+        return Boolean.TRUE.equals(flag);
+    }
+
+    public void releaseOrderLock(Long orderId) {
+        redisTemplate.delete(RedisKeys.MINT_ORDER_LOCK + orderId);
+    }
+}

+ 7 - 0
src/main/java/com/izouma/nineth/web/MintOrderController.java

@@ -96,6 +96,13 @@ public class MintOrderController extends BaseController {
         return mintOrderService.create(SecurityUtils.getAuthenticatedUser(), assetIds, mintActivityId, addressId);
     }
 
+    @PostMapping("/testCreate")
+    public String testCreate(@RequestParam String assets, @RequestParam Long mintActivityId, Long addressId) {
+        LongArrayConverter lc = new LongArrayConverter();
+        List<Long> assetIds = lc.convertToEntityAttribute(assets);
+        return mintOrderService.testCreate(SecurityUtils.getAuthenticatedUser(), assetIds, mintActivityId, addressId);
+    }
+
     @PreAuthorize("hasAnyRole('ADMIN','SAAS')")
     @ApiOperation("导出")
     @PostMapping("/excelPhone")

+ 1 - 1
src/test/java/com/izouma/nineth/CommonTest.java

@@ -778,6 +778,6 @@ public class CommonTest {
 
     @Test
     public void testrandomize() {
-        System.out.println(randomize(6, 1000));
+        System.out.println(DateTimeUtils.format(LocalDate.now(), "yy/MM/dd: "));
     }
 }

+ 0 - 6
src/test/java/com/izouma/nineth/service/MintOrderServiceTest.java

@@ -43,12 +43,6 @@ class MintOrderServiceTest extends ApplicationTests {
     @Autowired
     private RocketMQTemplate rocketMQTemplate;
 
-    @Test
-    void exchange() throws InterruptedException {
-        mintOrderService.create(9972L, Arrays.asList(134607L, 132435L, 132433L));
-        Thread.sleep(1000);
-    }
-
     @Test
     public void test1() {
         User user = userRepo.findByIdAndDelFalse(9972L).orElse(null);