licailing 3 жил өмнө
parent
commit
e3819e98f5

+ 3 - 0
src/main/java/com/izouma/nineth/config/RedisKeys.java

@@ -42,4 +42,7 @@ public class RedisKeys {
     public static final String PAY_TMP = "payTmp::";
 
     public static final String AUCTION_STATUS = "auctionStatus::";
+
+    public static final String AUCTION_ORDER_LOCK = "auctionOrderLock::";
+
 }

+ 121 - 84
src/main/java/com/izouma/nineth/service/AuctionOrderService.java

@@ -7,9 +7,12 @@ import com.izouma.nineth.enums.*;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.*;
 import com.izouma.nineth.utils.JpaUtils;
+import com.izouma.nineth.utils.SnowflakeIdWorker;
 import lombok.AllArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.data.domain.Page;
+import org.springframework.data.redis.core.BoundValueOperations;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
@@ -18,7 +21,9 @@ import java.time.LocalDateTime;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
+@Slf4j
 @Service
 @AllArgsConstructor
 public class AuctionOrderService {
@@ -33,6 +38,7 @@ public class AuctionOrderService {
     private UserAddressRepo               userAddressRepo;
     private AuctionActivityService        auctionActivityService;
     private RedisTemplate<String, Object> redisTemplate;
+    private SnowflakeIdWorker             snowflakeIdWorker;
 
     public Page<AuctionOrder> all(PageQuery pageQuery) {
         return auctionOrderRepo.findAll(JpaUtils.toSpecification(pageQuery, AuctionOrder.class), JpaUtils.toPageRequest(pageQuery));
@@ -53,6 +59,10 @@ public class AuctionOrderService {
             case PASS:
             case FINISH:
                 throw new BusinessException("拍卖已结束");
+            case FIXED_PRICE_PURCHASED:
+                if (AuctionPaymentType.FIXED_PRICE.equals(type)) {
+                    throw new BusinessException("一口价成交中");
+                }
         }
 
         if (AuctionPaymentType.DEPOSIT.equals(type)) {
@@ -75,44 +85,50 @@ public class AuctionOrderService {
             }
         }
 
-        if (AuctionSource.TRANSFER.equals(auction.getSource())) {
-            Asset asset = assetRepo.findById(auction.getAssetId()).orElseThrow(new BusinessException("资产不存在"));
-            asset.setStatus(AssetStatus.AUCTIONING);
-            assetRepo.save(asset);
-        }
-
-//        auction.setStatus(AuctionStatus.PURCHASED);
-//        auctionActivityRepo.save(auction);
-        auctionActivityService.changeStatus(auctionId, AuctionPaymentType.FIXED_PRICE.equals(type) ? AuctionStatus.FIXED_PRICE_PURCHASED : AuctionStatus.PURCHASED);
-
-        BigDecimal price = AuctionPaymentType.FIXED_PRICE.equals(type) ? auction.getFixedPrice() : auction.getPurchasePrice();
-
         UserAddress userAddress = null;
         if (addressId != null) {
             userAddress = userAddressRepo.findById(addressId).orElseThrow(new BusinessException("地址信息不存在"));
         }
 
-        AuctionOrder order = AuctionOrder.builder()
-                .auctionId(auction.getId())
-                .userId(user.getId())
-                .nickname(user.getNickname())
-                .paymentType(type)
-                .name(auction.getName())
-                .pic(auction.getPic())
-                .serviceCharge(auction.getServiceCharge())
-                .royalties(auction.getRoyalties())
-                .source(auction.getSource())
-                .price(price)
-                .totalPrice(price)
-                .auctionRecordId(auctionRecordId)
-                .status(AuctionOrderStatus.NOT_PAID)
-                .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))
-                .build();
+        try {
 
-        return auctionOrderRepo.save(order);
+            //        auction.setStatus(AuctionStatus.PURCHASED);
+//        auctionActivityRepo.save(auction);
+            auctionActivityService.changeStatus(auctionId, AuctionPaymentType.FIXED_PRICE.equals(type) ? AuctionStatus.FIXED_PRICE_PURCHASED : AuctionStatus.PURCHASED);
 
+            if (AuctionSource.TRANSFER.equals(auction.getSource())) {
+                Asset asset = assetRepo.findById(auction.getAssetId()).orElseThrow(new BusinessException("资产不存在"));
+                asset.setStatus(AssetStatus.AUCTIONING);
+                assetRepo.save(asset);
+            }
+
+            BigDecimal price = AuctionPaymentType.FIXED_PRICE.equals(type) ? auction.getFixedPrice() : auction.getPurchasePrice();
+
+            AuctionOrder order = AuctionOrder.builder()
+                    .id(snowflakeIdWorker.nextId())
+                    .auctionId(auction.getId())
+                    .userId(user.getId())
+                    .nickname(user.getNickname())
+                    .paymentType(type)
+                    .name(auction.getName())
+                    .pic(auction.getPic())
+                    .serviceCharge(auction.getServiceCharge())
+                    .royalties(auction.getRoyalties())
+                    .source(auction.getSource())
+                    .price(price)
+                    .totalPrice(price)
+                    .auctionRecordId(auctionRecordId)
+                    .status(AuctionOrderStatus.NOT_PAID)
+                    .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))
+                    .build();
+
+            return auctionOrderRepo.save(order);
+        } catch (Exception e) {
+            auctionActivityService.changeStatus(auctionId, AuctionStatus.ONGOING);
+            throw e;
+        }
     }
 
 
@@ -133,6 +149,7 @@ public class AuctionOrderService {
         }
 
         order = AuctionOrder.builder()
+                .id(snowflakeIdWorker.nextId())
                 .auctionId(auction.getId())
                 .userId(user.getId())
                 .nickname(user.getNickname())
@@ -205,70 +222,90 @@ public class AuctionOrderService {
     }
 
     public void cancel(AuctionOrder order) {
-        AuctionActivity auction = auctionActivityRepo.findById(order.getAuctionId())
-                .orElseThrow(new BusinessException("无记录"));
+        if (!getOrderLock(order.getId())) {
+            log.error("订单取消失败 {}, redis锁了", order.getId());
+            return;
+        }
 
-        if (AuctionPaymentType.PURCHASE_PRICE.equals(order.getPaymentType())) {
-            //如果是拍卖,需获取取消订单的时长
-            int time = sysConfigService.getInt("auction_cancel_time");
-            if (LocalDateTime.now().isAfter(auction.getEndTime().plusMinutes(time))) {
-                //超过支付时长
-//                auction.setStatus(AuctionStatus.PASS);
-//                auctionActivityRepo.save(auction);
+        try {
+            AuctionActivity auction = auctionActivityRepo.findById(order.getAuctionId())
+                    .orElseThrow(new BusinessException("无记录"));
+
+            if (AuctionPaymentType.PURCHASE_PRICE.equals(order.getPaymentType())) {
+                //如果是拍卖,需获取取消订单的时长
+                int time = sysConfigService.getInt("auction_cancel_time");
+                if (LocalDateTime.now().isAfter(auction.getEndTime().plusMinutes(time))) {
+                    //超过支付时长
+//                  auction.setStatus(AuctionStatus.PASS);
+//                  auctionActivityRepo.save(auction);
+                    auctionActivityService.changeStatus(order.getAuctionId(), AuctionStatus.PASS);
+
+                    //退其余保证金
+                    List<AuctionOrder> orders = auctionOrderRepo.findAllByAuctionIdAndPaymentTypeAndStatus(order.getAuctionId(),
+                            AuctionPaymentType.DEPOSIT, AuctionOrderStatus.FINISH);
+                    orders.stream()
+                            .filter(o -> !order.getUserId().equals(o.getUserId()))
+                            .forEach(o -> {
+                                //退款(暂未写)
+                                o.setRefundTime(LocalDateTime.now());
+                                o.setStatus(AuctionOrderStatus.REFUNDING);
+                                auctionOrderRepo.save(o);
+                            });
+
+                }
+            } else if (AuctionPaymentType.DEPOSIT.equals(order.getPaymentType())) {
+                //删除出价记录
+                auctionRecordRepo.softDelete(order.getAuctionRecordId());
+            } else {
+                //拍卖是否结束
+                if (LocalDateTime.now().isBefore(auction.getEndTime())) {
+                    //返回拍卖状态
+//                  auction.setStatus(AuctionStatus.ONGOING);
+                    auctionActivityService.changeStatus(order.getAuctionId(), AuctionStatus.ONGOING);
+
+                } else {
+//                  auction.setStatus(AuctionStatus.PASS);
+                    //退还保证金
+                    List<AuctionOrder> orders = auctionOrderRepo.findAllByAuctionIdAndPaymentTypeAndStatus(order.getAuctionId(),
+                            AuctionPaymentType.DEPOSIT, AuctionOrderStatus.FINISH);
+                    orders.forEach(o -> {
+                        //退款(暂未写)
+                        o.setRefundTime(LocalDateTime.now());
+                        o.setStatus(AuctionOrderStatus.REFUNDING);
+                        auctionOrderRepo.save(o);
+                    });
+                }
+//              auctionActivityRepo.save(auction);
                 auctionActivityService.changeStatus(order.getAuctionId(), AuctionStatus.PASS);
 
-                //退其余保证金
-                List<AuctionOrder> orders = auctionOrderRepo.findAllByAuctionIdAndPaymentTypeAndStatus(order.getAuctionId(),
-                        AuctionPaymentType.DEPOSIT, AuctionOrderStatus.FINISH);
-                orders.stream()
-                        .filter(o -> !order.getUserId().equals(o.getUserId()))
-                        .forEach(o -> {
-                            //退款(暂未写)
-                            o.setRefundTime(LocalDateTime.now());
-                            o.setStatus(AuctionOrderStatus.REFUNDING);
-                            auctionOrderRepo.save(o);
-                        });
-
             }
-        } else if (AuctionPaymentType.DEPOSIT.equals(order.getPaymentType())) {
-            //删除出价记录
-            auctionRecordRepo.softDelete(order.getAuctionRecordId());
-        } else {
-            //拍卖是否结束
-            if (LocalDateTime.now().isBefore(auction.getEndTime())) {
-                //返回拍卖状态
-//                auction.setStatus(AuctionStatus.ONGOING);
-                auctionActivityService.changeStatus(order.getAuctionId(), AuctionStatus.ONGOING);
 
-            } else {
-//                auction.setStatus(AuctionStatus.PASS);
-                //退还保证金
-                List<AuctionOrder> orders = auctionOrderRepo.findAllByAuctionIdAndPaymentTypeAndStatus(order.getAuctionId(),
-                        AuctionPaymentType.DEPOSIT, AuctionOrderStatus.FINISH);
-                orders.forEach(o -> {
-                    //退款(暂未写)
-                    o.setRefundTime(LocalDateTime.now());
-                    o.setStatus(AuctionOrderStatus.REFUNDING);
-                    auctionOrderRepo.save(o);
-                });
+            if (AuctionSource.TRANSFER.equals(order.getSource())) {
+                //改回资产状态
+                Asset asset = assetRepo.findById(auction.getAssetId()).orElseThrow(new BusinessException("资产不存在"));
+                asset.setStatus(AssetStatus.NORMAL);
+                assetRepo.save(asset);
             }
-//            auctionActivityRepo.save(auction);
-            auctionActivityService.changeStatus(order.getAuctionId(), AuctionStatus.PASS);
 
-        }
+            order.setStatus(AuctionOrderStatus.CANCELLED);
+            order.setCancelTime(LocalDateTime.now());
+            auctionOrderRepo.save(order);
+            log.info("取消订单{}", order.getId());
 
-        if (AuctionSource.TRANSFER.equals(order.getSource())) {
-            //改回资产状态
-            Asset asset = assetRepo.findById(auction.getAssetId()).orElseThrow(new BusinessException("资产不存在"));
-            asset.setStatus(AssetStatus.NORMAL);
-            assetRepo.save(asset);
+        } catch (Exception e) {
+            log.error("订单取消错误 orderId: " + order.getId(), e);
         }
+        releaseOrderLock(order.getId());
+    }
 
-        order.setStatus(AuctionOrderStatus.CANCELLED);
-        order.setCancelTime(LocalDateTime.now());
-        auctionOrderRepo.save(order);
-
+    public boolean getOrderLock(Long orderId) {
+        BoundValueOperations<String, Object> ops = redisTemplate.boundValueOps(RedisKeys.AUCTION_ORDER_LOCK + orderId);
+        Boolean flag = ops.setIfAbsent(1, 1, TimeUnit.DAYS);
+        return Boolean.TRUE.equals(flag);
     }
 
+    public void releaseOrderLock(Long orderId) {
+        redisTemplate.delete(RedisKeys.AUCTION_ORDER_LOCK + orderId);
+    }
 
 }