...
|
...
|
@@ -2,35 +2,35 @@ package com.yohoufo.order.service.impl; |
|
|
|
|
|
import com.yoho.error.ServiceError;
|
|
|
import com.yoho.error.exception.ServiceException;
|
|
|
import com.yohobuy.ufo.model.order.bo.GoodsInfo;
|
|
|
import com.yohobuy.ufo.model.order.bo.SoldPrdComputeBo;
|
|
|
import com.yohobuy.ufo.model.order.common.*;
|
|
|
import com.yohobuy.ufo.model.order.req.*;
|
|
|
import com.yohobuy.ufo.model.order.resp.BatchChangePriceResp;
|
|
|
import com.yohobuy.ufo.model.order.resp.OrderCntResp;
|
|
|
import com.yohobuy.ufo.model.order.resp.OrderListInfo;
|
|
|
import com.yohobuy.ufo.model.order.resp.PageResp;
|
|
|
import com.yohoufo.common.alarm.EventBusPublisher;
|
|
|
import com.yohoufo.common.alarm.SmsAlarmEvent;
|
|
|
import com.yohoufo.common.exception.GatewayException;
|
|
|
import com.yohoufo.common.utils.AddressUtil;
|
|
|
import com.yohoufo.common.utils.BigDecimalHelper;
|
|
|
import com.yohoufo.common.utils.DateUtil;
|
|
|
import com.yohoufo.dal.order.*;
|
|
|
import com.yohoufo.dal.order.model.*;
|
|
|
import com.yohoufo.order.common.*;
|
|
|
import com.yohoufo.dal.order.BuyerOrderMapper;
|
|
|
import com.yohoufo.dal.order.SellerOrderGoodsMapper;
|
|
|
import com.yohoufo.dal.order.SellerOrderMapper;
|
|
|
import com.yohoufo.dal.order.model.BuyerOrder;
|
|
|
import com.yohoufo.dal.order.model.SellerOrder;
|
|
|
import com.yohoufo.dal.order.model.SellerOrderGoods;
|
|
|
import com.yohoufo.order.common.ActionStatusHold;
|
|
|
import com.yohoufo.order.common.DelStatus;
|
|
|
import com.yohoufo.order.convert.SellerOrderConvertor;
|
|
|
import com.yohoufo.order.event.ErpCancelSellerOrderEvent;
|
|
|
import com.yohoufo.order.event.EventHandlerContainer;
|
|
|
import com.yohoufo.order.event.OrderCancelEvent;
|
|
|
import com.yohoufo.order.model.AddressInfo;
|
|
|
import com.yohobuy.ufo.model.order.bo.GoodsInfo;
|
|
|
import com.yohoufo.order.model.SellerOrderContext;
|
|
|
import com.yohoufo.order.model.dto.EarnestMoney;
|
|
|
import com.yohoufo.order.model.dto.PlatformFeeDto;
|
|
|
import com.yohoufo.order.model.dto.SellerOrderComputeResult;
|
|
|
import com.yohoufo.order.model.request.OrderListRequest;
|
|
|
import com.yohoufo.order.model.request.OrderRequest;
|
|
|
import com.yohoufo.order.model.response.OrderDetailInfo;
|
|
|
import com.yohobuy.ufo.model.order.resp.OrderListInfo;
|
|
|
import com.yohoufo.order.model.response.OrderSubmitResp;
|
|
|
import com.yohoufo.order.model.response.OrderSummaryResp;
|
|
|
import com.yohoufo.order.service.IOrderDetailService;
|
...
|
...
|
@@ -39,16 +39,12 @@ import com.yohoufo.order.service.cache.CacheCleaner; |
|
|
import com.yohoufo.order.service.cache.OrderCacheService;
|
|
|
import com.yohoufo.order.service.handler.SellerOrderComputeHandler;
|
|
|
import com.yohoufo.order.service.handler.SellerOrderSubmitHandler;
|
|
|
import com.yohoufo.order.service.impl.processor.SellerOrderPrepareProcessor;
|
|
|
import com.yohoufo.order.service.impl.visitor.OffShelveCancelCase;
|
|
|
import com.yohoufo.order.service.impl.visitor.UserCancelCase;
|
|
|
import com.yohoufo.order.service.proxy.ProductProxyService;
|
|
|
import com.yohoufo.order.service.proxy.UserProxyService;
|
|
|
import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator;
|
|
|
import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta;
|
|
|
import com.yohoufo.order.utils.AddressHelper;
|
|
|
import com.yohoufo.product.model.GoodsSize;
|
|
|
import com.yohoufo.product.model.ProductInfo;
|
|
|
import com.yohoufo.product.response.StorageDataResp;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
...
|
...
|
@@ -67,7 +63,6 @@ import java.util.stream.Collectors; |
|
|
@Slf4j
|
|
|
public class SellerOrderService implements IOrderListService, IOrderDetailService {
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderMapper sellerOrderMapper;
|
|
|
|
...
|
...
|
@@ -84,9 +79,6 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
private SellerOrderSubmitHandler orderSubmitHandler;
|
|
|
|
|
|
@Autowired
|
|
|
private UserProxyService userProxyService;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderListService sellerOrderListService;
|
|
|
|
|
|
@Autowired
|
...
|
...
|
@@ -110,6 +102,8 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
@Autowired
|
|
|
private CacheCleaner cacheCleaner;
|
|
|
|
|
|
@Autowired
|
|
|
private SellerOrderPrepareProcessor sellerOrderPrepareProcessor;
|
|
|
|
|
|
public SoldPrdComputeBo computePublishPrd(SellerOrderComputeReq req) throws GatewayException {
|
|
|
log.info("in computePublishPrd, req {}", req);
|
...
|
...
|
@@ -152,33 +146,10 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
log.warn("in computePublishPrd price convert BigDecimal fail, {}", req);
|
|
|
throw new GatewayException(400, "非法数字");
|
|
|
}
|
|
|
checkPrice(storageId, prdPrice, false);
|
|
|
sellerOrderPrepareProcessor.checkPrice(storageId, prdPrice, false);
|
|
|
return buildSoldPrdComputeBo(uid, num, prdPrice);
|
|
|
}
|
|
|
|
|
|
|
|
|
void checkPrice(int storageId, BigDecimal prdPrice, boolean validateMaxPrice) throws GatewayException {
|
|
|
ProductInfo productInfo = productProxyService.getPrdPriceRange(storageId);
|
|
|
BigDecimal minPrice = productInfo.getMinPrice();
|
|
|
BigDecimal maxPrice = productInfo.getMaxPrice();
|
|
|
if (prdPrice.subtract(minPrice).doubleValue() < 0D){
|
|
|
log.warn("in computePublishPrd,minPrice {}, storageId {}", minPrice, storageId);
|
|
|
throw new GatewayException(501, "您的出价过低");
|
|
|
}
|
|
|
|
|
|
if (validateMaxPrice && prdPrice.subtract(maxPrice).doubleValue() > 0D){
|
|
|
log.warn("in computePublishPrd,maxPrice {}, storageId {}", maxPrice, storageId);
|
|
|
throw new GatewayException(501, "您的出价过高");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void checkIncome(int storageId, BigDecimal income) throws GatewayException {
|
|
|
if (income == null || income.compareTo(BigDecimal.ZERO) <= 0){
|
|
|
log.warn("in checkIncome,storageId {}, income {}", income);
|
|
|
throw new GatewayException(501, "别闹了,这个售价没有收入");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 发布商品 + 生成订单
|
|
|
* @param req
|
...
|
...
|
@@ -187,22 +158,22 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
*/
|
|
|
|
|
|
public OrderSubmitResp publishPrd(SellerOrderSubmitReq req) throws GatewayException {
|
|
|
SellerOrderContext context = buildSellerOrderContext(req);
|
|
|
SellerOrderContext context = sellerOrderPrepareProcessor.buildSellerOrderContext(req);
|
|
|
int storageId = context.getStorageId();
|
|
|
int uid = context.getUid();
|
|
|
//step 1: rpc get product detail by storage id
|
|
|
//ufo.product.storage.data
|
|
|
GoodsInfo goodsInfo = getProductDetail(context);
|
|
|
GoodsInfo goodsInfo = sellerOrderPrepareProcessor.getProductDetail(context);
|
|
|
//step 2: generate skup ,action :set price status(unsaleable)
|
|
|
if (Objects.isNull(goodsInfo)){
|
|
|
log.warn("in computePublishPrd storageId not exist in prd , uid {}, storageId {}", uid, storageId);
|
|
|
log.warn("in publishPrd storageId not exist in prd service , uid {}, storageId {}", uid, storageId);
|
|
|
throw new ServiceException(ServiceError.ORDER_ORDERS_GOODS_IS_EMPTY);
|
|
|
}
|
|
|
context.setSoldProduct(goodsInfo);
|
|
|
checkPrice(storageId, goodsInfo.getPrice(), true);
|
|
|
sellerOrderPrepareProcessor.checkPrice(storageId, goodsInfo.getPrice(), true);
|
|
|
// compute every fee from price
|
|
|
SellerOrderComputeResult computeResult = computeHandler.compute(goodsInfo.getPrice());
|
|
|
checkIncome(storageId, computeResult.getIncome());
|
|
|
sellerOrderPrepareProcessor.checkIncome(storageId, computeResult.getIncome());
|
|
|
log.info("in publishPrd , uid {}, storageId {}, price {}, computeResult {}", uid, storageId,
|
|
|
goodsInfo.getPrice(), computeResult);
|
|
|
context.setSellerOrderComputeResult(computeResult);
|
...
|
...
|
@@ -248,98 +219,6 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private GoodsInfo getProductDetail(SellerOrderContext context){
|
|
|
int uid = context.getUid();
|
|
|
int storageId = context.getStorageId();
|
|
|
BigDecimal salePrice = context.getSalePrice();
|
|
|
try {
|
|
|
StorageDataResp prdResp = productProxyService.getStorageData(storageId);
|
|
|
|
|
|
if (!Integer.valueOf(1).equals(prdResp.getStatus())) {
|
|
|
log.info("in getProductDetail occur product out shelve, uid {}, storageId {}", uid, storageId);
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
GoodsInfo goodsInfo = new GoodsInfo();
|
|
|
goodsInfo.setUid(uid);
|
|
|
goodsInfo.setProductId(prdResp.getProductId());
|
|
|
goodsInfo.setProductName(prdResp.getProductName());
|
|
|
goodsInfo.setColorId(Objects.isNull(prdResp.getColorId()) ? null : Integer.valueOf(prdResp.getColorId()));
|
|
|
goodsInfo.setColorName(prdResp.getColorName());
|
|
|
GoodsSize size;
|
|
|
if (Objects.nonNull(size =prdResp.getSize())){
|
|
|
goodsInfo.setSizeName(size.getSizeName());
|
|
|
goodsInfo.setSizeId(size.getSizeId());
|
|
|
}
|
|
|
goodsInfo.setImageUrl(prdResp.getImageUrl());
|
|
|
goodsInfo.setPrice(salePrice);
|
|
|
goodsInfo.setStorageId(context.getStorageId());
|
|
|
return goodsInfo;
|
|
|
}catch (Exception ex){
|
|
|
log.warn("in getProductDetail occur error, uid {}, storageId {}", uid, storageId);
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
private SellerOrderContext buildSellerOrderContext(SellerOrderSubmitReq req) throws GatewayException {
|
|
|
int uid = req.getUid();
|
|
|
if (uid <= 0){
|
|
|
log.warn("uid illegal , uid {}", uid);
|
|
|
throw new GatewayException(400, "Uid 错误");
|
|
|
}
|
|
|
Integer storageId = req.getStorageId();
|
|
|
if (storageId <=0 ){
|
|
|
log.warn("storageId illegal , uid {}", uid);
|
|
|
throw new GatewayException(400, "storageId 错误");
|
|
|
}
|
|
|
String price = req.getPrice();
|
|
|
if (StringUtils.isBlank(price)){
|
|
|
log.warn("in buildSellerOrderContext price illegal , req {}", req);
|
|
|
throw new GatewayException(400, "没有价格");
|
|
|
}
|
|
|
|
|
|
if(!price.endsWith("9")){
|
|
|
log.warn("in buildSellerOrderContext price illegal , req {}", req);
|
|
|
throw new GatewayException(400, "价格须为以9结尾的正整数");
|
|
|
}
|
|
|
|
|
|
BigDecimal salePrice;
|
|
|
try{
|
|
|
salePrice = new BigDecimal(req.getPrice());
|
|
|
}catch (Exception ex){
|
|
|
log.warn("storageId illegal , uid {}", uid);
|
|
|
throw new GatewayException(400, "售价格式错误");
|
|
|
}
|
|
|
|
|
|
int addressId = AddressUtil.getDecryptStr(req.getAddressId());
|
|
|
if (addressId < 0){
|
|
|
log.warn("seller submit order addressId invalidate, uid {}, storageId {}, addressId is {}",
|
|
|
uid, storageId, req.getAddressId());
|
|
|
throw new ServiceException(ServiceError.ORDER_ADDRESSID_INVALIDATE);
|
|
|
}
|
|
|
|
|
|
//the address of send back 2 seller
|
|
|
//
|
|
|
AddressInfo hiddenBackAddress = userProxyService.getHiddenAddressInfo(uid, addressId);
|
|
|
AddressInfo noHiddenBackAddress = userProxyService.getAddressInfoNotHidden(uid, addressId);
|
|
|
if(AddressHelper.isNeedUpdate(noHiddenBackAddress)){
|
|
|
log.warn("seller submit addressId need update, uid is {}, storageId is {}, addressId is {}",
|
|
|
uid, storageId, addressId);
|
|
|
throw new ServiceException(ServiceError.ORDER_ADDRESS_NEED_UPDATE);
|
|
|
}
|
|
|
//
|
|
|
SellerOrderContext context = new SellerOrderContext();
|
|
|
context.setUid(uid);
|
|
|
context.setStorageId(storageId);
|
|
|
context.setSalePrice(salePrice);
|
|
|
//
|
|
|
context.setBackAddress(noHiddenBackAddress);
|
|
|
context.setBackHiddenAddress(hiddenBackAddress);
|
|
|
return context;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 卖家支付完成后调用
|
|
|
* @param uid
|
...
|
...
|
@@ -361,6 +240,21 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
|
|
|
}
|
|
|
|
|
|
@Autowired
|
|
|
private SkupBatchService skupBatchService;
|
|
|
|
|
|
public void batchPublishPrds(SellerOrderSubmitReq req) throws GatewayException {
|
|
|
// 一串校验
|
|
|
SellerOrderContext ctx = sellerOrderPrepareProcessor.buildBatchSellerOrderContext(req);
|
|
|
//TODO 扣减保证金
|
|
|
//TODO (异步实现)记录保证金流水
|
|
|
//TODO 生成批次号
|
|
|
skupBatchService.generateBatchNo(req.getUid(), req.getNum());
|
|
|
//TODO 批量生成订单(订单表,meta 地址,算费)--> 需要用到多线程并行处理
|
|
|
//TODO(异步实现)同步数据到prd,记录支付,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
public boolean offShelveByErp(int skup){
|
|
|
if (skup <= 0 ){
|
...
|
...
|
@@ -447,16 +341,14 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
|
|
|
if(OrderCodeType.BUYER_TYPE.getType() == codeMeta.getType()){
|
|
|
BuyerOrder buyerOrder = buyerOrderMapper.selectAllByOrderCode(orderCode);
|
|
|
//todo 判断状态后更新
|
|
|
//判断状态后更新
|
|
|
checkBuyCanDelStatus(buyerOrder.getStatus());
|
|
|
|
|
|
BuyerOrder target = new BuyerOrder();
|
|
|
target.setId(buyerOrder.getId());
|
|
|
target.setSellerOrderStatus(DelStatus.IS_DEL.getCode());
|
|
|
target.setUpdateTime(DateUtil.getCurrentTimeSecond());
|
|
|
buyerOrderMapper.updateByPrimaryKeySelective(target);
|
|
|
}
|
|
|
|
|
|
cacheCleaner.cleanList(uid, TabType.SELL.getValue());
|
|
|
return true;
|
|
|
}
|
...
|
...
|
@@ -488,29 +380,12 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private boolean isEnough(int uid, BigDecimal mEarestMoney){
|
|
|
|
|
|
//todo 取出入驻商家的钱包余额,判断保证金总额是否足够扣减
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
private SoldPrdComputeBo buildSoldPrdComputeBo(int uid, int num, BigDecimal prdPrice){
|
|
|
SellerOrderComputeResult computeResult = computeHandler.compute(prdPrice);
|
|
|
/**
|
|
|
* 验证是否是入驻商家
|
|
|
*/
|
|
|
boolean isEntryShop = userProxyService.isEntryShop(uid);
|
|
|
if(isEntryShop){
|
|
|
BigDecimal singleEarestMoney = computeResult.getEarnestMoney().getEarnestMoney();
|
|
|
BigDecimal mEarestMoney = BigDecimalHelper.halfUp(new BigDecimal(num).multiply(singleEarestMoney));
|
|
|
|
|
|
boolean isEnough = isEnough(uid, mEarestMoney);
|
|
|
if (!isEnough){
|
|
|
|
|
|
throw new ServiceException(ServiceError.WALLET_EARNESTMONEY_IS_NOT_ENOUGH);
|
|
|
}
|
|
|
}
|
|
|
sellerOrderPrepareProcessor.checkNGetMergeEarnestMoney(uid, computeResult, num, prdPrice);
|
|
|
SoldPrdComputeBo computeBo = SellerOrderConvertor.computeResult2SoldPrdComputeBo(computeResult);
|
|
|
return computeBo;
|
|
|
}
|
...
|
...
|
@@ -528,8 +403,6 @@ public class SellerOrderService implements IOrderListService, IOrderDetailServi |
|
|
return sellerOrderDetailService.getOrderDetail(orderRequest);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
* 根据用户id查询卖的单数
|
|
|
* 出售栏目显示的数量=出售tab下商品“出售中”状态的数量+待发货tab下所有的订单数+已发货tab下所有订单数
|
...
|
...
|
|