Browse Source

竞拍链路集成

hr~ 1 tháng trước cách đây
mục cha
commit
8965919586

+ 5 - 1
bid/src/main/java/cn/hobbystocks/auc/handle/SkuSoldHandler.java

@@ -51,10 +51,14 @@ public class SkuSoldHandler implements SoldHandler {
         Order order =new Order();
         order.setLotId(soldEvent.getLotId());
         order.setSkuId(soldEvent.getGoodsId());
+        order.setUserId(soldEvent.getUserId());
+        order.setAmount(soldEvent.getAmount());
+        if (Objects.nonNull(soldEvent.getLot())) {
+            order.setMerchantId(soldEvent.getLot().getMerchantId());
+        }
         //创建订单并保存数据库
         OrderVO orderVO = orderService.createSkuOrder(order);
         if (Objects.nonNull(orderVO.getExpireTime())) {
-
             lotMapper.updatePay(soldEvent.getLotId(), -1);
             soldEvent.getLot().setPaid(-1L);
         }

+ 9 - 9
bid/src/main/java/cn/hobbystocks/auc/listener/SoldListener.java

@@ -35,22 +35,22 @@ public class SoldListener {
         log.info("handle sold event {}", soldEvent);
         try {
             int count = soldOrderRecordMapper.insertRecord(
-                    SoldOrderRecord.builder()
-                            .lotId(soldEvent.getLotId())
-                            .bidId(soldEvent.getBidId())
-                            .createTime(new Date())
-                            .build());
+                SoldOrderRecord.builder()
+                    .lotId(soldEvent.getLotId())
+                    .bidId(soldEvent.getBidId())
+                    .createTime(new Date())
+                    .build());
             if (count <= 0) {
                 log.error("handled sold event {}", soldEvent);
                 return;
             }
             Lot lot = lotMapper.selectLotById(soldEvent.getLotId());
 
-                if(soldHandlerHolder.handle(soldEvent)) {
-                    soldOrderRecordMapper.updateOrder(soldEvent.getOrderId(), soldEvent.getLotId());
-                }
+            if (soldHandlerHolder.handle(soldEvent)) {
+                soldOrderRecordMapper.updateOrder(soldEvent.getOrderId(), soldEvent.getLotId());
+            }
 
-        }catch (Exception e) {
+        } catch (Exception e) {
             log.error("handle sold event {}", soldEvent, e);
         }
     }

+ 12 - 3
bid/src/main/java/cn/hobbystocks/auc/task/BidTask.java

@@ -121,13 +121,22 @@ public class BidTask implements CacheMap {
      */
     @Override
     public void putLive(Live live){
+        if (Objects.isNull(live) || Objects.isNull(live.getLot())) {
+            return;
+        }
+        live.getLot().setProperties(null);
         live = CloneUtils.clone(live);
-        ConcurrentHashMap<String, Live> cacheMap = liveCacheMap.get(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, live.getLot().getAuctionId()));
+        if (Objects.isNull(live) || Objects.isNull(live.getLot())) {
+            return;
+        }
+        Long auctionId = live.getLot().getAuctionId();
+        Long lotId = live.getLot().getId();
+        ConcurrentHashMap<String, Live> cacheMap = liveCacheMap.get(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, auctionId));
         if (Objects.isNull(cacheMap)) {
             cacheMap = new ConcurrentHashMap<>();
         }
-        cacheMap.put(live.getLot().getId().toString(), live);
-        liveCacheMap.put(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, live.getLot().getAuctionId()), cacheMap);
+        cacheMap.put(lotId.toString(), live);
+        liveCacheMap.put(String.format(Constants.REDIS_MAP_AUC_LOT_TEMPLATE, auctionId), cacheMap);
     }
 
     /**

+ 6 - 0
bid/src/main/java/cn/hobbystocks/auc/web/LocalController.java

@@ -39,6 +39,12 @@ public class LocalController {
     @Autowired
     private IOrderService orderService;
 
+    @ApiOperation(value = "测试创建中拍订单", notes = "仅用于当前服务内联调 createSkuOrder")
+    @PostMapping("/order/create/test")
+    public AjaxResult createSkuOrderForTest(@RequestBody Order order) {
+        return AjaxResult.success(orderService.createSkuOrder(order));
+    }
+
     @ApiOperation(value = "查询拍品是否正在竞拍",notes = "检查拍品ID数组的拍卖是否正在进行")
     @PostMapping("/lot/status")
     public AjaxResult living(@RequestBody LotGroupVO lotGroup) {

+ 1 - 1
bid/src/main/resources/application-dev.yml

@@ -15,7 +15,7 @@ spring:
 hobbystocks:
   host:
     pointUrl: http://app/api/local/v1/point/operate
-    orderUrl: http://order/api/local/v1/order/auction/submit
+    orderUrl: http://py-app/api/v5/lot/order/create
     noticeUrl: http://app/api/local/v1/notify/mail #站内信通知
     couponUrl: http://app/api/local/v1/coupon/send
     imUrl: http://poyee-im/chat/handler

+ 1 - 1
bid/src/main/resources/application-local.yml

@@ -20,7 +20,7 @@ hobbystocks:
       nodes: ${SENTINEL_NODES:192.168.50.8:26379}
   host:
     pointUrl: http://app/api/local/v1/point/operate
-    orderUrl: http://order/api/local/v1/order/auction/submit
+    orderUrl: http://127.0.0.1:8082/api/v5/lot/order/create
     noticeUrl: http://poyee-im/chat/handler #IM服务通知
     couponUrl: http://app/api/local/v1/coupon/send
     imUrl: http://poyee-im/chat/handler

+ 16 - 3
lot/src/main/java/cn/hobbystocks/auc/common/core/redis/RedisCache.java

@@ -4,9 +4,11 @@ import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
+import cn.hobbystocks.auc.handle.context.Live;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.BoundSetOperations;
 import org.springframework.data.redis.core.HashOperations;
@@ -33,7 +35,7 @@ public class RedisCache {
 	 * @param value 缓存的值
 	 */
 	public <T> void setCacheObject(final String key, final T value) {
-		redisTemplate.opsForValue().set(key, value);
+		redisTemplate.opsForValue().set(key, sanitizeCacheValue(value));
 	}
 
 	/**
@@ -45,7 +47,7 @@ public class RedisCache {
 	 * @param timeUnit 时间颗粒度
 	 */
 	public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
-		redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
+		redisTemplate.opsForValue().set(key, sanitizeCacheValue(value), timeout, timeUnit);
 	}
 
 	/**
@@ -186,6 +188,7 @@ public class RedisCache {
 	 */
 	public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
 		if (dataMap != null) {
+			dataMap.replaceAll((mapKey, value) -> sanitizeCacheValue(value));
 			redisTemplate.opsForHash().putAll(key, dataMap);
 		}
 	}
@@ -208,7 +211,17 @@ public class RedisCache {
 	 * @param value 值
 	 */
 	public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
-		redisTemplate.opsForHash().put(key, hKey, value);
+		redisTemplate.opsForHash().put(key, hKey, sanitizeCacheValue(value));
+	}
+
+	private <T> T sanitizeCacheValue(T value) {
+		if (value instanceof Live) {
+			Live live = (Live) value;
+			if (Objects.nonNull(live.getLot())) {
+				live.getLot().setProperties(null);
+			}
+		}
+		return value;
 	}
 
 	public <T> void deleteCacheMapValue(final String key, final String hKey) {

+ 44 - 0
lot/src/main/java/cn/hobbystocks/auc/dto/OrderApiResponse.java

@@ -0,0 +1,44 @@
+package cn.hobbystocks.auc.dto;
+
+import cn.hobbystocks.auc.common.exception.ServiceException;
+import cn.hobbystocks.auc.vo.OrderVO;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.Map;
+import java.util.Objects;
+
+@Data
+public class OrderApiResponse {
+    private Boolean success;
+    private Integer code;
+    private String msg;
+    private Map<String, LotOrderResponse> data;
+
+    public OrderVO toOrderVO() {
+        if (!Objects.equals(Boolean.TRUE, success) || !Objects.equals(0, code)) {
+            throw new ServiceException(Objects.toString(msg, "创建订单失败"));
+        }
+        LotOrderResponse lotOrder = data == null ? null : data.get("lotOrder");
+        if (lotOrder == null) {
+            lotOrder = data == null ? null : data.get("order");
+        }
+        if (lotOrder == null) {
+            throw new ServiceException("创建订单失败:订单服务未返回订单信息");
+        }
+        OrderVO orderVO = new OrderVO();
+        orderVO.setOrderId(lotOrder.getId());
+        orderVO.setOrderNo(lotOrder.getOrderNo());
+        orderVO.setStatus(lotOrder.getStatus());
+        orderVO.setExpireTime(lotOrder.getExpireTime());
+        return orderVO;
+    }
+
+    @Data
+    public static class LotOrderResponse {
+        private Long id;
+        private String orderNo;
+        private Integer status;
+        private Date expireTime;
+    }
+}

+ 20 - 15
lot/src/main/java/cn/hobbystocks/auc/dto/SkuOrderDTO.java

@@ -2,27 +2,32 @@ package cn.hobbystocks.auc.dto;
 
 import lombok.Data;
 
-import java.math.BigDecimal;
+import java.util.Date;
 
 @Data
 public class SkuOrderDTO {
-    //商品skuId
-    private int skuId;
-    //拍卖服务费
-    private BigDecimal serviceExpense;
-    //用户id
+    // 商品spuId
+    private long spuId;
+    // 拍卖服务费(分)
+    private long serviceExpense;
+    // 用户id
     private long userId;
-    //拍卖成交价(分)
-    private long amount;
-    //订单过期时间
-    private long expireTime;
-    //拍卖会名称
+    // 订单金额(分)
+    private long paymentAmount;
+    // 订单总价(分)
+    private long totalAmount;
+    // 订单过期时间
+    private Date expireTime;
+    // 拍卖会id
+    private long auctionId;
+    // 拍卖会名称
     private String auctionName;
-    //拍品id
+    // 拍品id
     private long lotId;
-    //拍品名称
+    // 拍品名称
     private String lotName;
-    //商家id
+    // 拍品图片
+    private String lotImage;
+    // 商家id
     private long merchantId;
-
 }

+ 6 - 28
lot/src/main/java/cn/hobbystocks/auc/forest/OrderApi.java

@@ -1,40 +1,18 @@
 package cn.hobbystocks.auc.forest;
 
-import cn.hobbystocks.auc.dto.DepositOrderDTO;
+import cn.hobbystocks.auc.dto.OrderApiResponse;
 import cn.hobbystocks.auc.dto.SkuOrderDTO;
-import cn.hobbystocks.auc.vo.OrderVO;
 import com.dtflys.forest.annotation.BaseRequest;
-import com.dtflys.forest.annotation.Body;
+import com.dtflys.forest.annotation.JSONBody;
 import com.dtflys.forest.annotation.Post;
+import com.dtflys.forest.annotation.Var;
 
 @BaseRequest(baseURL = "")
 public interface OrderApi {
 
     /**
-     * 创建sku订单
+     * 创建拍品订单
      */
-    @Post(url = "")
-    OrderVO createSkuOrder(@Body SkuOrderDTO orderDTO);
-
-    /**
-     * 创建保证金订单
-     */
-    @Post("")
-    OrderVO createDepositOrder(@Body DepositOrderDTO depositOrderDTO);
-
-    /**
-     * 保证金订单退款
-     * @param orderVO
-     * @return 订单状态
-     */
-    @Post("")
-    OrderVO refundDepositOrder(OrderVO orderVO);
-
-    /**
-     * 扣减保证金
-     * @param orderVO 订单号
-     * @return 订单状态
-     */
-    @Post("")
-    OrderVO reduceDeposit(OrderVO orderVO);
+    @Post("{url}")
+    OrderApiResponse createSkuOrder(@Var("url") String url, @JSONBody SkuOrderDTO orderDTO);
 }

+ 1 - 28
lot/src/main/java/cn/hobbystocks/auc/service/impl/LotServiceImpl.java

@@ -724,34 +724,7 @@ public class LotServiceImpl extends ServiceImpl<LotMapper,Lot> implements ILotSe
     }
 
     private void sortSelfLots(String type, List<LotVO> lots) {
-        if ("waiting".equals(type)) {
-            lots.sort(Comparator.comparing(Lot::getStartTime, Comparator.nullsLast(Date::compareTo)));
-            return;
-        }
-        if ("live".equals(type)) {
-            lots.sort(Comparator.comparing(Lot::getLastPriceTime, Comparator.nullsLast(Date::compareTo)).reversed());
-            return;
-        }
-        if ("lose".equals(type) || "pass".equals(type) || "finish".equals(type) || "win".equals(type)) {
-            lots.sort(Comparator.comparing(Lot::getRealEndTime, Comparator.nullsLast(Date::compareTo)).reversed());
-            return;
-        }
-
-        List<LotVO> waiting = lots.stream().filter(lot -> "waiting".equals(lot.getSelfStatus()))
-                .sorted(Comparator.comparing(Lot::getStartTime, Comparator.nullsLast(Date::compareTo)))
-                .collect(Collectors.toList());
-        List<LotVO> live = lots.stream()
-                .filter(lot -> "live".equals(lot.getSelfStatus()))
-                .sorted(Comparator.comparing(Lot::getLastPriceTime, Comparator.nullsLast(Date::compareTo)).reversed())
-                .collect(Collectors.toList());
-        List<LotVO> lose = lots.stream()
-                .filter(lot -> "lose".equals(lot.getSelfStatus()) || "win".equals(lot.getSelfStatus()))
-                .sorted(Comparator.comparing(Lot::getRealEndTime, Comparator.nullsLast(Date::compareTo)).reversed())
-                .collect(Collectors.toList());
-        lots.clear();
-        lots.addAll(waiting);
-        lots.addAll(live);
-        lots.addAll(lose);
+        lots.sort(Comparator.comparing(Lot::getCreateTime, Comparator.nullsLast(Comparator.reverseOrder())));
     }
 
     private List<LotVO> finishOrWin(Integer win) {

+ 42 - 30
lot/src/main/java/cn/hobbystocks/auc/service/impl/OrderServiceImpl.java

@@ -1,9 +1,11 @@
 package cn.hobbystocks.auc.service.impl;
 
+import cn.hobbystocks.auc.common.exception.ServiceException;
 import cn.hobbystocks.auc.common.utils.DateUtils;
 import cn.hobbystocks.auc.domain.Auction;
 import cn.hobbystocks.auc.domain.Lot;
 import cn.hobbystocks.auc.domain.Order;
+import cn.hobbystocks.auc.dto.OrderApiResponse;
 import cn.hobbystocks.auc.dto.SkuOrderDTO;
 import cn.hobbystocks.auc.forest.OrderApi;
 import cn.hobbystocks.auc.mapper.OrderMapper;
@@ -12,18 +14,20 @@ import cn.hobbystocks.auc.service.ILotService;
 import cn.hobbystocks.auc.service.IOrderService;
 import cn.hobbystocks.auc.vo.OrderVO;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 @Service
-public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements IOrderService {
+public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {
 
     @Autowired
     ILotService lotService;
@@ -31,43 +35,36 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements
     IAuctionService auctionService;
     @Resource
     OrderApi orderApi;
-
-
-
+    @Value("${hobbystocks.host.orderUrl}")
+    private String orderUrl;
 
     @Override
     @Transactional
     public OrderVO createSkuOrder(Order order) {
-        //查询拍品服务费
         Lot lot = lotService.selectLotById(order.getLotId());
         Auction auction = auctionService.selectAuctionById(lot.getAuctionId());
         BigDecimal serviceTariff = lot.getServiceTariff();
         Integer payTimeLimit = lot.getPayTimeLimit();
-        if (serviceTariff==null){
-            //查询拍卖会服务费
-            serviceTariff=auction.getServiceTariff();
+        if (serviceTariff == null) {
+            serviceTariff = auction.getServiceTariff();
+        }
+        if (payTimeLimit == null) {
+            payTimeLimit = auction.getPayTimeLimit();
         }
-        if (payTimeLimit==null)
-            //中拍支付时限(小时)
-            payTimeLimit=auction.getPayTimeLimit();
-        //计算服务费
-        long amount = order.getAmount();
-        BigDecimal bigAmount = BigDecimal.valueOf(amount);
-        //费率/100*成交价=服务费
-        BigDecimal serviceExpense = serviceTariff.divide(BigDecimal.valueOf(100)).multiply(bigAmount);
+        if (Objects.isNull(order.getAmount())) {
+            throw new ServiceException("创建订单失败:成交金额为空");
+        }
+
+        BigDecimal amount = BigDecimal.valueOf(order.getAmount());
+        BigDecimal serviceExpense = serviceTariff.multiply(amount)
+                .divide(BigDecimal.valueOf(100), 0, RoundingMode.HALF_UP);
         order.setServiceExpense(serviceExpense);
-        //根据支付时限计算订单过期时间,
-        Date date = DateUtils.addHours(new Date(), payTimeLimit);
-        order.setExpireTime(date);
+        Date expireTime = DateUtils.addHours(new Date(), payTimeLimit);
+        order.setExpireTime(expireTime);
         save(order);
 
-        //todo 调用创建订单接口
-        SkuOrderDTO skuOrderDTO = new SkuOrderDTO();
-        BeanUtils.copyProperties(order,skuOrderDTO);
-        skuOrderDTO.setAuctionName(auction.getName());
-        skuOrderDTO.setLotName(lot.getName());
-        OrderVO orderVO = orderApi.createSkuOrder(skuOrderDTO);
-        //todo 记录订单信息
+        OrderApiResponse response = orderApi.createSkuOrder(orderUrl, buildSkuOrderDTO(order, lot, auction));
+        OrderVO orderVO = response.toOrderVO();
         order.setOrderId(orderVO.getOrderId());
         order.setOrderNo(orderVO.getOrderNo());
         order.setStatus(orderVO.getStatus());
@@ -75,6 +72,23 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements
         return orderVO;
     }
 
+    SkuOrderDTO buildSkuOrderDTO(Order order, Lot lot, Auction auction) {
+        SkuOrderDTO skuOrderDTO = new SkuOrderDTO();
+        skuOrderDTO.setLotId(order.getLotId());
+        skuOrderDTO.setSpuId(order.getSkuId());
+        skuOrderDTO.setUserId(order.getUserId());
+        skuOrderDTO.setAuctionId(lot.getAuctionId());
+        skuOrderDTO.setAuctionName(auction.getName());
+        skuOrderDTO.setLotName(lot.getName());
+        skuOrderDTO.setLotImage(lot.getImgs());
+        skuOrderDTO.setMerchantId(Objects.isNull(order.getMerchantId()) ? lot.getMerchantId() : order.getMerchantId());
+        skuOrderDTO.setPaymentAmount(order.getAmount());
+        skuOrderDTO.setServiceExpense(order.getServiceExpense().longValue());
+        skuOrderDTO.setTotalAmount(BigDecimal.valueOf(order.getAmount()).add(order.getServiceExpense()).longValue());
+        skuOrderDTO.setExpireTime(order.getExpireTime());
+        return skuOrderDTO;
+    }
+
     @Override
     public int modifyOrder(Order order) {
         return getBaseMapper().updateOrderStatus(order);
@@ -82,8 +96,6 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper,Order> implements
 
     @Override
     public List<Order> getOrderListByUserAndAuction(Long auctionId, Integer userId) {
-        return getBaseMapper().selectOrderByAuctionId(auctionId,userId);
+        return getBaseMapper().selectOrderByAuctionId(auctionId, userId);
     }
-
-
 }