|
|
@@ -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);
|
|
|
+ }
|
|
|
|
|
|
}
|