wangqifan преди 3 години
родител
ревизия
a32a5f0e76

+ 6 - 3
src/main/java/com/izouma/nineth/config/Constants.java

@@ -54,7 +54,8 @@ public interface Constants {
         String MINT     = "mintOrder";
         String RECHARGE = "recharge";
         String AUCTION  = "auctionOrder";
-        String PIC  = "picOrder";
+        String PIC      = "picOrder";
+        String DOMAIN   = "domain";
     }
 
     interface Rarity {
@@ -79,7 +80,9 @@ public interface Constants {
 
     }
 
-    List<AssetStatus> META_INOPERABLE_STATUS = List.of(AssetStatus.AUCTIONED, AssetStatus.DESTROYED, AssetStatus.GIFTED, AssetStatus.TRANSFERRED);
+    List<AssetStatus> META_INOPERABLE_STATUS = List
+            .of(AssetStatus.AUCTIONED, AssetStatus.DESTROYED, AssetStatus.GIFTED, AssetStatus.TRANSFERRED);
 
-    List<AssetStatus> META_NORMAL_STATUS = List.of(AssetStatus.NORMAL, AssetStatus.TRADING, AssetStatus.GIFTING, AssetStatus.MINTING, AssetStatus.AUCTIONING);
+    List<AssetStatus> META_NORMAL_STATUS = List
+            .of(AssetStatus.NORMAL, AssetStatus.TRADING, AssetStatus.GIFTING, AssetStatus.MINTING, AssetStatus.AUCTIONING);
 }

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

@@ -338,4 +338,33 @@ public class Asset extends CollectionBaseEntity {
                 .chainFlag(2)
                 .build();
     }
+
+    public static Asset create(DomainOrder domainOrder, User user) {
+        return Asset.builder()
+                .userId(user.getId())
+                .collectionId(domainOrder.getId())
+                .minter(user.getNickname())
+                .minterId(user.getId())
+                .minterAvatar(user.getAvatar())
+                .name("元域名:" + domainOrder.getDomainName())
+                .detail(null)
+                .pic(Collections.singletonList(null))
+                .model3d(null)
+                .category("元域名")
+                .canResale(false)
+                .royalties(0)
+                .serviceCharge(0)
+                .price(BigDecimal.ZERO)
+                .status(AssetStatus.NORMAL)
+                .owner(user.getNickname())
+                .ownerId(user.getId())
+                .ownerAvatar(user.getAvatar())
+                .type(CollectionType.DEFAULT)
+                .holdDays(null)
+                .oldHoldDays(null)
+                .source(AssetSource.OFFICIAL)
+                .companyId(1L)
+                .chainFlag(2)
+                .build();
+    }
 }

+ 7 - 6
src/main/java/com/izouma/nineth/event/OrderNotifyEvent.java

@@ -11,12 +11,13 @@ import java.io.Serializable;
 @AllArgsConstructor
 @NoArgsConstructor
 public class OrderNotifyEvent implements Serializable {
-    public static final String TYPE_ORDER      = "order";
-    public static final String TYPE_MINT_ORDER = "mint_order";
-    public static final String TYPE_GIFT_ORDER = "gift_order";
-    public static final String TYPE_RECHARGE   = "recharge";
-    public static final String TYPE_AUCTION_ORDER   = "auction_order";
-    public static final String TYPE_PIC   = "pic_order";
+    public static final String TYPE_ORDER         = "order";
+    public static final String TYPE_MINT_ORDER    = "mint_order";
+    public static final String TYPE_GIFT_ORDER    = "gift_order";
+    public static final String TYPE_RECHARGE      = "recharge";
+    public static final String TYPE_AUCTION_ORDER = "auction_order";
+    public static final String TYPE_PIC           = "pic_order";
+    public static final String DOMAIN             = "domain";
 
     private Long      orderId;
     private PayMethod payMethod;

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

@@ -26,6 +26,7 @@ public class OrderNotifyListener implements RocketMQListener<OrderNotifyEvent> {
     private UserBalanceService  userBalanceService;
     private AuctionOrderService auctionOrderService;
     private PhotoAssetService   photoAssetService;
+    private DomainOrderService  domainOrderService;
 
     @Override
     public void onMessage(OrderNotifyEvent e) {
@@ -50,6 +51,10 @@ public class OrderNotifyListener implements RocketMQListener<OrderNotifyEvent> {
                 //星图回调
                 photoAssetService.notify(e.getOrderId(), e.getPayMethod(), e.getTransactionId());
                 break;
+            case OrderNotifyEvent.DOMAIN:
+                //星图回调
+                domainOrderService.notify(e.getOrderId(), e.getPayMethod(), e.getTransactionId());
+                break;
             case OrderNotifyEvent.TYPE_ORDER:
             default:
                 orderService.notifyOrder(e.getOrderId(), e.getPayMethod(), e.getTransactionId());

+ 37 - 0
src/main/java/com/izouma/nineth/service/AssetService.java

@@ -255,6 +255,43 @@ public class AssetService {
         return asset;
     }
 
+    public Asset createAsset(DomainOrder domainOrder, User user, Long orderId, BigDecimal price, String type,
+                             Integer number, boolean safeFlag) {
+        Asset asset = Asset.create(domainOrder, user);
+        asset.setTokenId(TokenUtils.genTokenId());
+        asset.setNumber(number);
+        asset.setOrderId(orderId);
+        asset.setPrice(price);
+        asset.setPrefixName("元域名");
+        asset.setTags(new HashSet<>());
+        User fakeUser = null;
+        if (safeFlag) {
+            fakeUser = createFakeUser();
+            asset.setOwner(fakeUser.getNickname());
+            asset.setOwnerId(fakeUser.getId());
+            asset.setOwnerAvatar(fakeUser.getAvatar());
+        }
+        assetRepo.saveAndFlush(asset);
+        tokenHistoryRepo.save(TokenHistory.builder()
+                .tokenId(asset.getTokenId())
+                .fromUser(domainOrder.getUserName())
+                .fromUserId(domainOrder.getUserId())
+                .fromAvatar(domainOrder.getUserAvatar())
+                .toUser((safeFlag ? fakeUser : user).getNickname())
+                .toUserId((safeFlag ? fakeUser : user).getId())
+                .toAvatar((safeFlag ? fakeUser : user).getAvatar())
+                .operation(type)
+                .price(price)
+                .companyId(asset.getCompanyId())
+                .build());
+
+        //绿洲石
+//        rockRecordService.addRock(user.getId(), price, "购买");
+
+        rocketMQTemplate.syncSend(generalProperties.getMintTopic(), asset.getId());
+        return asset;
+    }
+
     public synchronized int getMessedNumber(Long collectionId, int number, int total) {
         NumberSeq numberSeq = numberSeqRepo.findById(collectionId).orElse(null);
         if (numberSeq == null || numberSeq.getTotal() != total) {

+ 37 - 2
src/main/java/com/izouma/nineth/service/DomainOrderService.java

@@ -1,19 +1,23 @@
 package com.izouma.nineth.service;
 
 import com.izouma.nineth.domain.DomainOrder;
+import com.izouma.nineth.domain.PhotoAsset;
 import com.izouma.nineth.domain.User;
 import com.izouma.nineth.dto.PageQuery;
 import com.izouma.nineth.enums.CollectionStatus;
 import com.izouma.nineth.enums.OrderStatus;
+import com.izouma.nineth.enums.PayMethod;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.DomainOrderRepo;
 import com.izouma.nineth.repo.UserRepo;
 import com.izouma.nineth.utils.JpaUtils;
 import lombok.AllArgsConstructor;
+import org.springframework.data.annotation.Transient;
 import org.springframework.data.domain.Page;
 import org.springframework.stereotype.Service;
 
 import javax.print.DocFlavor;
+import java.math.BigDecimal;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -26,13 +30,14 @@ public class DomainOrderService {
     private DomainOrderRepo     domainOrderRepo;
     private ContentAuditService contentAuditService;
     private UserRepo            userRepo;
+    private AssetService        assetService;
 
     public Page<DomainOrder> all(PageQuery pageQuery) {
         return domainOrderRepo
                 .findAll(JpaUtils.toSpecification(pageQuery, DomainOrder.class), JpaUtils.toPageRequest(pageQuery));
     }
 
-    public DomainOrder create(Long userId, String domain) {
+    public DomainOrder create(Long userId, String domain, BigDecimal price) {
         if (domain.length() < 5) {
             throw new BusinessException("四位及以下域名只能官方创建。");
         }
@@ -40,6 +45,9 @@ public class DomainOrderService {
         if (!(Boolean) checkResult.get("result")) {
             throw new BusinessException(checkResult.get("reason").toString());
         }
+        if (price.compareTo(BigDecimal.valueOf(40L)) != 0) {
+            throw new BusinessException("订单价格与配置不符,请重新下单.");
+        }
         User user = userRepo.findById(userId).orElseThrow(new BusinessException("未找到用户"));
         if (domain.contains(".")) {
             int dotIndex = domain.indexOf(".");
@@ -47,8 +55,9 @@ public class DomainOrderService {
         }
         DomainOrder domainOrder = new DomainOrder();
         domainOrder.setPicName(domain);
+        domainOrder.setPrice(price);
         domainOrder.setDomainName(domain + ".uni");
-        domainOrder.setStatus(CollectionStatus.SUCCESS);
+        domainOrder.setStatus(CollectionStatus.PENDING);
         domainOrder.setUserId(user.getId());
         domainOrder.setUserAvatar(user.getAvatar());
         domainOrder.setUserName(user.getNickname());
@@ -111,4 +120,30 @@ public class DomainOrderService {
         });
         return result;
     }
+
+    @Transient
+    public void notify(Long id, PayMethod payMethod, String transactionId) {
+        DomainOrder domainOrder = domainOrderRepo.findById(id).orElseThrow(new BusinessException("未找到星图"));
+        if (!domainOrder.getOrderStatus().equals(OrderStatus.NOT_PAID)) {
+            throw new BusinessException("订单已经处理");
+        }
+        domainOrder.setOrderStatus(OrderStatus.FINISH);
+        domainOrder.setPayMethod(payMethod);
+        domainOrder.setTransactionId(transactionId);
+        domainOrder.setStatus(CollectionStatus.SUCCESS);
+        createAsset(domainOrder);
+        domainOrderRepo.save(domainOrder);
+    }
+
+    public void cancel(DomainOrder domainOrder) {
+        domainOrder.setOrderStatus(OrderStatus.CANCELLED);
+        domainOrder.setStatus(CollectionStatus.FAIL);
+        domainOrderRepo.save(domainOrder);
+    }
+
+    public void createAsset(DomainOrder domainOrder) {
+        Long createId = assetService.createAsset(domainOrder, userRepo.findById(domainOrder.getUserId())
+                .orElseThrow(new BusinessException("无用户记录")), null, BigDecimal.ZERO, "域名", null, false).getId();
+    }
+
 }

+ 105 - 2
src/main/java/com/izouma/nineth/service/OrderPayService.java

@@ -67,6 +67,8 @@ public class OrderPayService {
     private final AlipayService       alipayService;
     private final PhotoAssetRepo      photoAssetRepo;
     private final PhotoAssetService   photoAssetService;
+    private final DomainOrderService  domainOrderService;
+    private final DomainOrderRepo     domainOrderRepo;
 
     public static void setPayChannel(String payChannel) {
         log.info("set pay channel {}", payChannel);
@@ -733,7 +735,8 @@ public class OrderPayService {
             case Constants.PayChannel.HM:
                 return hmPayService.requestAlipay(orderId + "", order.getPrice(),
                         "星图:" + order.getPicName(), HMPayService.getTimeout(order.getCreatedAt(), 180),
-                        Constants.OrderNotifyType.PIC, generalProperties.resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId));
+                        Constants.OrderNotifyType.PIC, generalProperties
+                                .resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId));
         }
         throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
     }
@@ -755,7 +758,8 @@ public class OrderPayService {
                     .encode(Constants.ALIPAY_URL_SCHEME + qrCode, StandardCharsets.UTF_8)
                     + "&orderId=" + orderId + "&type=pic&returnUrl="
                     + URLEncoder
-                    .encode(generalProperties.resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId), StandardCharsets.UTF_8);
+                    .encode(generalProperties
+                            .resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId), StandardCharsets.UTF_8);
         } else {
             return Constants.ALIPAY_URL_SCHEME + qrCode;
         }
@@ -816,4 +820,103 @@ public class OrderPayService {
         return payEaseService.pay("星图:" + order.getPicName(), orderId.toString(), order.getPrice(),
                 order.getUserId().toString(), bindCardId, Constants.OrderNotifyType.PIC);
     }
+
+    @Cacheable(value = "payOrder", key = "'domain#'+#orderId")
+    public String payDomainOrder(Long orderId) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        switch (PAY_CHANNEL) {
+            case Constants.PayChannel.SAND:
+                return sandPayService.pay(orderId + "", "域名:" + order.getPicName(), order.getPrice(),
+                        order.getCreatedAt().plusMinutes(3), Constants.OrderNotifyType.DOMAIN);
+            case Constants.PayChannel.HM:
+                return hmPayService.requestAlipay(orderId + "", order.getPrice(),
+                        "域名:" + order.getPicName(), HMPayService.getTimeout(order.getCreatedAt(), 180),
+                        Constants.OrderNotifyType.DOMAIN, generalProperties
+                                .resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId));
+        }
+        throw new BusinessException("绿洲宇宙冷却系统已启动,请稍后支付");
+    }
+
+    @Cacheable(value = "payOrder", key = "'domain#'+#orderId")
+    public String payDomainAli(Long orderId) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+
+        String qrCode = aliRequest(orderId, order.getPrice(), "域名:" + order
+                .getPicName(), Constants.OrderNotifyType.DOMAIN);
+
+        String ua = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
+                .getHeader("User-Agent");
+        if (ua.toLowerCase().contains("micromessenger")) {
+            return "/static/wx_alipay_bridge.html?payUrl=" + URLEncoder
+                    .encode(Constants.ALIPAY_URL_SCHEME + qrCode, StandardCharsets.UTF_8)
+                    + "&orderId=" + orderId + "&type=domain&returnUrl="
+                    + URLEncoder
+                    .encode(generalProperties
+                            .resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId), StandardCharsets.UTF_8);
+        } else {
+            return Constants.ALIPAY_URL_SCHEME + qrCode;
+        }
+    }
+
+    @Cacheable(value = "payOrder", key = "'domain#'+#orderId")
+    public String payDomainQuick(Long orderId) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        IdentityAuth identityAuth = identityAuthRepo
+                .findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(order.getUserId(), AuthStatus.SUCCESS)
+                .orElseThrow(new BusinessException("请先完成实名认证"));
+        return sandPayService.payQuick(orderId + "", "域名:" + order.getPicName(),
+                order.getPrice(), order.getCreatedAt().plusMinutes(3), Constants.OrderNotifyType.DOMAIN,
+                generalProperties.resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId));
+    }
+
+    @Cacheable(value = "payOrder", key = "'domain#'+#orderId")
+    public String payDomainQuickBind(Long orderId) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        IdentityAuth identityAuth = identityAuthRepo
+                .findFirstByUserIdAndStatusAndDelFalseOrderByCreatedAtDesc(order.getUserId(), AuthStatus.SUCCESS)
+                .orElseThrow(new BusinessException("请先完成实名认证"));
+        return sandPayService.payQuickBind(orderId + "", "域名:" + order.getPicName(),
+                order.getPrice(), order.getCreatedAt().plusMinutes(3), Constants.OrderNotifyType.DOMAIN,
+                generalProperties.resolveFrontUrl(getCompanyId(), "/orderDetail?id=" + orderId),
+                order.getUserId(), identityAuth.getRealName(), identityAuth.getIdNo());
+    }
+
+    public void payDomainOrderBalance(Long orderId, Long userId, String tradeCode) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        checkTradeCode(userId, tradeCode, order.getUserId());
+        BalanceRecord record = userBalanceService.balancePay(order.getUserId(), order.getPrice(), orderId, "域名");
+        domainOrderService.notify(orderId, PayMethod.BALANCE, record.getId().toString());
+    }
+
+    @Cacheable(value = "payOrder", key = "'domain#'+#orderId")
+    public Map<String, Object> payDomainOrderAgreement(Long orderId, String bindCardId) {
+        DomainOrder order = domainOrderRepo.findById(orderId).orElseThrow(new BusinessException("订单不存在"));
+        if (order.getOrderStatus() != OrderStatus.NOT_PAID) {
+            throw new BusinessException("订单状态错误");
+        }
+        if (StringUtils.isEmpty(bindCardId)) {
+            bindCardId = userBankCardRepo.findByUserId(order.getUserId())
+                    .stream().map(UserBankCard::getBindCardId).findFirst().orElse(null);
+        }
+        if (StringUtils.isEmpty(bindCardId)) {
+            throw new BusinessException("请先绑定银行卡");
+        }
+        return payEaseService.pay("域名:" + order.getPicName(), orderId.toString(), order.getPrice(),
+                order.getUserId().toString(), bindCardId, Constants.OrderNotifyType.DOMAIN);
+    }
 }

+ 5 - 0
src/main/java/com/izouma/nineth/web/AlipayNotifyController.java

@@ -84,6 +84,11 @@ public class AlipayNotifyController {
                             new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
                                     System.currentTimeMillis(), OrderNotifyEvent.TYPE_PIC));
                     break;
+                case "domain":
+                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                            new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,
+                                    System.currentTimeMillis(), OrderNotifyEvent.DOMAIN));
+                    break;
                 case "auctionOrder":
                     rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
                             new OrderNotifyEvent(orderId, PayMethod.ALIPAY, tradeNo,

+ 3 - 2
src/main/java/com/izouma/nineth/web/DomainOrderController.java

@@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.math.BigDecimal;
 import java.util.List;
 import java.util.Map;
 
@@ -43,8 +44,8 @@ public class DomainOrderController extends BaseController {
     }
 
     @PostMapping("/create")
-    public DomainOrder create(Long userId, String domain) {
-        return domainOrderService.create(userId, domain);
+    public DomainOrder create(Long userId, String domain, BigDecimal price) {
+        return domainOrderService.create(userId, domain, price);
     }
 
     @PostMapping("/search")

+ 8 - 3
src/main/java/com/izouma/nineth/web/HmPayController.java

@@ -26,9 +26,9 @@ import java.util.stream.Collectors;
 @Slf4j
 @AllArgsConstructor
 public class HmPayController extends BaseController {
-    private final HmPayProperties    hmPayProperties;
-    private final RocketMQTemplate   rocketMQTemplate;
-    private final GeneralProperties  generalProperties;
+    private final HmPayProperties   hmPayProperties;
+    private final RocketMQTemplate  rocketMQTemplate;
+    private final GeneralProperties generalProperties;
 
     @GetMapping("/notify/{type}/{id}")
     public String orderNotify(@PathVariable String type, @PathVariable Long id, HttpServletRequest req) throws AlipayApiException {
@@ -77,6 +77,11 @@ public class HmPayController extends BaseController {
                             new OrderNotifyEvent(id, PayMethod.SANDPAY, plat_trx_no,
                                     System.currentTimeMillis(), OrderNotifyEvent.TYPE_PIC));
                     break;
+                case "domain":
+                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                            new OrderNotifyEvent(id, PayMethod.SANDPAY, plat_trx_no,
+                                    System.currentTimeMillis(), OrderNotifyEvent.DOMAIN));
+                    break;
             }
         }
         return "SUCCESS";

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

@@ -292,4 +292,10 @@ public class OrderPayControllerV2 {
     public Map<String, Object> payPicAgreement(@RequestParam Long id, String bindCardId) {
         return orderPayService.payPicOrderAgreement(id, bindCardId);
     }
+
+    @RequestMapping(value = "/domain/balance")
+    @ResponseBody
+    public void payDomainOrderBalance(@RequestParam Long id, @RequestParam String tradeCode) {
+        orderPayService.payDomainOrderBalance(id, SecurityUtils.getAuthenticatedUser().getId(), tradeCode);
+    }
 }

+ 5 - 0
src/main/java/com/izouma/nineth/web/PayEaseController.java

@@ -67,6 +67,11 @@ public class PayEaseController {
                             new OrderNotifyEvent(id, PayMethod.SANDPAY, serialNumber,
                                     System.currentTimeMillis(), OrderNotifyEvent.TYPE_PIC));
                     break;
+                case "domain":
+                    rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                            new OrderNotifyEvent(id, PayMethod.SANDPAY, serialNumber,
+                                    System.currentTimeMillis(), OrderNotifyEvent.DOMAIN));
+                    break;
             }
         }
         return "SUCCESS";

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

@@ -84,6 +84,11 @@ public class SandPayController {
                                         new OrderNotifyEvent(id, PayMethod.SANDPAY, payOrderCode,
                                                 System.currentTimeMillis(), OrderNotifyEvent.TYPE_PIC));
                                 break;
+                            case "domain":
+                                rocketMQTemplate.syncSend(generalProperties.getOrderNotifyTopic(),
+                                        new OrderNotifyEvent(id, PayMethod.SANDPAY, payOrderCode,
+                                                System.currentTimeMillis(), OrderNotifyEvent.DOMAIN));
+                                break;
                         }
                     }
                     return "respCode=000000";