Jelajahi Sumber

feat:抖音抖店订单拉取

xuyongjun 1 tahun lalu
induk
melakukan
f1e44a97e7

+ 8 - 0
watero-rst-service/pom.xml

@@ -34,6 +34,14 @@
             <version>2.0-2023</version>
         </dependency>
 
+        <!-- 抖音抖店sdk -->
+        <!-- http://maven.iamberry.com/#view-repositories;thirdparty~browsestorage -->
+        <dependency>
+            <groupId>com.jinritemai</groupId>
+            <artifactId>sdk-java</artifactId>
+            <version>1.1.0-20230621123120</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 44 - 0
watero-rst-service/src/main/java/com/iamberry/rst/service/cm/SalesOrderServiceImpl.java

@@ -1,5 +1,9 @@
 package com.iamberry.rst.service.cm;
 
+import com.doudian.open.api.order_logisticsAdd.OrderLogisticsAddRequest;
+import com.doudian.open.api.order_logisticsAdd.OrderLogisticsAddResponse;
+import com.doudian.open.api.order_logisticsAdd.param.OrderLogisticsAddParam;
+import com.doudian.open.core.AccessTokenBuilder;
 import com.github.pagehelper.PageHelper;
 import com.iamberry.app.tool.util.AES;
 import com.iamberry.redis.RedisUtils;
@@ -31,6 +35,7 @@ import com.iamberry.rst.service.order.mapper.DeliveryStrategyMapper;
 import com.iamberry.rst.service.order.mapper.ProvincesLogisticsMapper;
 import com.iamberry.rst.service.product.mapper.ProductMapper;
 import com.iamberry.rst.service.sys.mapper.SysConfigMapper;
+import com.iamberry.rst.util.DouyinConfig;
 import com.iamberry.rst.util.JingdongConfig;
 import com.iamberry.rst.util.PageUtil;
 import com.iamberry.rst.util.TaobaoConfig;
@@ -43,6 +48,7 @@ import com.jd.open.api.sdk.JdException;
 import com.jd.open.api.sdk.domain.order.OrderQueryJsfService.response.enGet.OrderSearchInfo;
 import com.jd.open.api.sdk.domain.order.OrderShipmentService.response.shipment.OperatorResult;
 import com.jd.open.api.sdk.internal.util.HttpUtil;
+import com.jd.open.api.sdk.request.order.OrderLogisticsSearchRequest;
 import com.jd.open.api.sdk.request.order.PopOrderShipmentRequest;
 import com.jd.open.api.sdk.response.order.PopOrderShipmentResponse;
 import com.taobao.api.ApiException;
@@ -2299,6 +2305,44 @@ public class SalesOrderServiceImpl implements SalesOrderService {
                     throw new RuntimeException(e);
                 }
             }
+            // 抖音订单发货
+            if (salesOrder.getSalesBatchId().startsWith("DY")) {
+                try {
+                    Integer salesStoreId = salesOrder.getSalesStoreId();
+                    Long shopId;
+                    // 映射到抖音的shopId,保存的地方在DouyinTask中
+                    if (salesStoreId == 148) {
+                        shopId = DouyinConfig.DOUYIN_IAMBERRY_SHOP_ID;
+                    } else if (salesStoreId == 172) {
+                        shopId = DouyinConfig.DOUYIN_METAPURE_SHOP_ID;
+                    } else {
+                        throw new RuntimeException("未映射到抖音店铺,系统出小差啦~");
+                    }
+
+                    // 查询系统快递公司信息
+                    LogisticsInfo logisticsInfo = logisticsInfoService.getLogisticsNameByRSTCode(salesOrder.getSalesPostFirm());
+
+                    OrderLogisticsAddParam param = new OrderLogisticsAddParam();
+                    param.setOrderId(salesOrder.getSalesExOrderId());
+                    param.setLogisticsCode(salesOrder.getSalesPostNum());
+                    param.setCompany(logisticsInfo.getLogisticsName());
+                    // 这里抖音的快递公司编码和系统快递100的一样,就先不调用抖音的了
+                    param.setCompanyCode(logisticsInfo.getLogisticsOnehundredCode());
+
+                    OrderLogisticsAddRequest request = new OrderLogisticsAddRequest();
+                    request.setParam(param);
+                    OrderLogisticsAddResponse response = request.execute(AccessTokenBuilder.build(shopId));
+                    if (response.isSuccess()) {
+                        logger.info("抖音发货回传请求成功");
+                    } else {
+                        logger.info("抖音发货回传请求错误:{}", response.getMsg());
+                        throw new RuntimeException("抖音发货回传请求失败" );
+                    }
+                } catch (Exception e) {
+                    logger.error("抖音订单发货失败:", e);
+                    throw new RuntimeException(e);
+                }
+            }
             // 添加订单追踪信息
             OrderTracking orderTracking = new OrderTracking();
             orderTracking.setAdminId(currAdmin);

+ 17 - 0
watero-rst-service/src/main/java/com/iamberry/rst/util/DouyinConfig.java

@@ -0,0 +1,17 @@
+package com.iamberry.rst.util;
+
+/**
+ * @author xuyongjun
+ * @since 2023-07-06
+ */
+public class DouyinConfig {
+
+    /**
+     * 爱贝源小店shopid
+     */
+    public static final Long DOUYIN_IAMBERRY_SHOP_ID = 7971061L;
+    /**
+     * 美塔璞儿小店shopid
+     */
+    public static final Long DOUYIN_METAPURE_SHOP_ID = 89887499L;
+}

+ 12 - 0
watero-rst-service/src/main/java/com/iamberry/rst/util/GenerateKeyUtil.java

@@ -68,6 +68,9 @@ public class GenerateKeyUtil {
     private final static String SX_BATCH = "X";
     /*淘宝添加批次编号*/
     private final static String ST_BATCH = "T";
+    /** 抖音添加批次编号 */
+    private final static String DY_BATCH = "Y";
+
     /*获取redis编号前缀*/
     private final static String SC_DETECT = "detect_";
 
@@ -172,6 +175,15 @@ public class GenerateKeyUtil {
     }
 
     /**
+     * 获取批次号 setSalesBatchId -- 京东添加
+     * @return
+     */
+    public String getSalesBatchIdDY(){
+        Integer number = getBatch();
+        return ("D"+ DY_BATCH + SDF_BATCH.format(new Date()) + String.format("%08d", number));
+    }
+
+    /**
      * 获取批次号 setSalesBatchId -- 批量导入
      * @return
      */

+ 451 - 0
watero-rst-web/src/main/java/com/iamberry/rst/controllers/mq/DouyinTask.java

@@ -0,0 +1,451 @@
+package com.iamberry.rst.controllers.mq;
+
+import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptRequest;
+import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptResponse;
+import com.doudian.open.api.order_batchDecrypt.data.DecryptInfosItem;
+import com.doudian.open.api.order_batchDecrypt.data.OrderBatchDecryptData;
+import com.doudian.open.api.order_batchDecrypt.param.CipherInfosItem;
+import com.doudian.open.api.order_batchDecrypt.param.OrderBatchDecryptParam;
+import com.doudian.open.api.order_searchList.OrderSearchListRequest;
+import com.doudian.open.api.order_searchList.OrderSearchListResponse;
+import com.doudian.open.api.order_searchList.data.PostAddr;
+import com.doudian.open.api.order_searchList.data.ShopOrderListItem;
+import com.doudian.open.api.order_searchList.data.SkuOrderListItem;
+import com.doudian.open.api.order_searchList.param.CombineStatusItem;
+import com.doudian.open.api.order_searchList.param.OrderSearchListParam;
+import com.doudian.open.core.AccessToken;
+import com.doudian.open.core.AccessTokenBuilder;
+import com.doudian.open.core.GlobalConfig;
+import com.iamberry.rst.core.cm.SalesOrder;
+import com.iamberry.rst.core.cm.SalesOrderItem;
+import com.iamberry.rst.core.order.OrderSyncLog;
+import com.iamberry.rst.core.order.ProductColor;
+import com.iamberry.rst.core.order.ProductCombinatInfo;
+import com.iamberry.rst.core.sys.SysConfig;
+import com.iamberry.rst.faces.cm.SalesOrderService;
+import com.iamberry.rst.faces.sys.SysConfigService;
+import com.iamberry.rst.service.order.mapper.OrderSyncLogMapper;
+import com.iamberry.rst.service.product.mapper.ProductColorMapper;
+import com.iamberry.rst.service.product.mapper.ProductMapper;
+import com.iamberry.rst.util.GenerateKeyUtil;
+import com.iamberry.wechat.tools.DateTimeUtil;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+
+import static com.iamberry.rst.controllers.mq.TaobaoConfig.*;
+
+/**
+ * 抖音抖店订单同步
+ *
+ * @author xuyongjun
+ * @since 2023-06-20
+ */
+@Component
+@Lazy(false)
+public class DouyinTask {
+
+    private static Logger logger = LoggerFactory.getLogger(DouyinTask.class);
+
+    @Autowired
+    private SysConfigService sysConfigService;
+    @Autowired
+    private SalesOrderService salesOrderService;
+    @Autowired
+    private OrderSyncLogMapper orderSyncLogMapper;
+    @Autowired
+    private GenerateKeyUtil generateKeyUtil ;
+    @Autowired
+    private ProductColorMapper productColorMapper;
+    @Autowired
+    private ProductMapper productMapper;
+
+    /** 是否允许抓取抖店订单,true表示允许,false表示不允许 */
+    private static boolean isDebug = false;
+
+    static {
+        String debug = System.getProperty("isDouyin");
+        System.out.println("读取到的配置数据:" + debug);
+        if ("true".equalsIgnoreCase(debug)) {
+            isDebug = true;
+        }
+
+        GlobalConfig.initAppKey(TaobaoConfig.DOUYIN_APP_KEY);
+        GlobalConfig.initAppSecret(TaobaoConfig.DOUYIN_APP_SECRET);
+    }
+
+
+    /**
+     * 30分钟同步一次
+     */
+    @Scheduled(fixedDelay = 1000 * 60 * 10, initialDelay = 3000)
+    public void syncOrder() {
+        if (!isDebug) {
+            logger.info("【抖音订单】debug模式,无法运行正式任务");
+            return;
+        }
+        logger.info("【抖音订单】开始抓取数据......");
+
+        // 组装请求数据
+        SysConfig sysConfigTime = sysConfigService.getSysConfigAll(DB_DOUYIN_PULL_ORDER_LIMIT_TIME);
+        String startTime = sysConfigTime.getConfigParameter();
+        if (StringUtils.isEmpty(startTime)) {
+            startTime = String.valueOf(DateTimeUtil.addDay(-1).getTime() / 1000);
+            sysConfigTime.setConfigParameter(startTime);
+            sysConfigService.updateSysConfig(sysConfigTime);
+        }
+        // 结束时间
+        String endTime = String.valueOf(System.currentTimeMillis() / 1000);
+        logger.info("开始时间:{}, 结束时间:{}", startTime, endTime);
+
+        // 同时处理爱贝源小店和美塔璞儿小店
+        Long[] shopIds = new Long[]{TaobaoConfig.DOUYIN_IAMBERRY_SHOP_ID, DOUYIN_METAPURE_SHOP_ID};
+        for (Long shopId : shopIds) {
+            int rstSalesStoreId;
+            String accountId;
+            String accountType;
+            if (shopId.equals(DOUYIN_IAMBERRY_SHOP_ID)) {
+                // 抖音旗舰店
+                rstSalesStoreId = 148;
+                accountId = DOUYIN_IAMBERRY_ACCOUNT_ID;
+                accountType = DOUYIN_IAMBERRY_ACCOUNT_TYPE;
+            } else {
+                // 美塔璞儿的抖店
+                rstSalesStoreId = 172;
+                accountId = DOUYIN_METAPURE_ACCOUNT_ID;
+                accountType = DOUYIN_METAPURE_ACCOUNT_TYPE;
+            }
+
+            // 处理accessToken
+            AccessToken accessToken = AccessTokenBuilder.build(shopId);
+
+            // 批次号
+            String batchIdST = generateKeyUtil.getSalesBatchIdDY();
+            long page = 0L;
+            long size = 50L;
+            int total = 0;
+            List<ShopOrderListItem> shopOrderList = null;
+            try {
+                do {
+                    // 拉取订单
+                    OrderSearchListRequest request = new OrderSearchListRequest();
+                    OrderSearchListParam param = new OrderSearchListParam();
+                    param.setPage(page);
+                    param.setSize(size);
+                    List<CombineStatusItem> combineStatusItems = new ArrayList<>();
+                    CombineStatusItem combineStatusItem = new CombineStatusItem();
+                    // 已付款和待发货
+                    combineStatusItem.setOrderStatus("105,2");
+                    combineStatusItems.add(combineStatusItem);
+                    param.setCombineStatus(combineStatusItems);
+                    param.setCreateTimeStart(Long.parseLong(startTime));
+                    param.setCreateTimeEnd(Long.parseLong(endTime));
+                    request.setParam(param);
+                    OrderSearchListResponse response = request.execute(accessToken);
+                    shopOrderList = response.getData().getShopOrderList();
+                    if (CollectionUtils.isNotEmpty(shopOrderList)) {
+                        total += shopOrderList.size();
+                        for (ShopOrderListItem item : shopOrderList) {
+                            SalesOrder salesOrder = assembleSalesOrder(item, accessToken, rstSalesStoreId, accountId, accountType);
+                            if (salesOrder != null) {
+                                salesOrder.setSalesBatchId(batchIdST);
+                                salesOrderService.addOrder(salesOrder, "创建订单(抖音拉取订单)");
+                            }
+                        }
+                        page ++;
+                    }
+                } while (CollectionUtils.isNotEmpty(shopOrderList));
+
+                OrderSyncLog orderSyncLog = new OrderSyncLog();
+                orderSyncLog.setSyncPlatId(1);
+                orderSyncLog.setSyncLogType(1);
+                orderSyncLog.setSyncLogMode(1);
+                //同步总数量
+                orderSyncLog.setSyncLogRecentNum(total);
+                //同步失败数量
+                orderSyncLog.setSyncLogErrorNum(0);
+                //备注
+                orderSyncLog.setSyncLogMsg(String.format("拉取抖音店铺id(%d)订单", shopId));
+                orderSyncLogMapper.save(orderSyncLog);
+
+                // 更新同步时间
+                sysConfigTime.setConfigParameter(endTime);
+                sysConfigService.updateSysConfig(sysConfigTime);
+            } catch (Exception e) {
+                logger.error("拉取抖音订单失败:", e);
+                OrderSyncLog orderSyncLog = new OrderSyncLog();
+                orderSyncLog.setSyncPlatId(1);
+                orderSyncLog.setSyncLogType(1);
+                orderSyncLog.setSyncLogMode(1);
+                //同步总数量
+                orderSyncLog.setSyncLogRecentNum(1);
+                //同步失败数量
+                orderSyncLog.setSyncLogErrorNum(1);
+                //备注
+                orderSyncLog.setSyncLogMsg("拉取抖音订单");
+                orderSyncLog.setSyncLogErrorMsg(e.getMessage());
+                orderSyncLogMapper.save(orderSyncLog);
+            }
+        }
+
+    }
+
+    /**
+     * 组装数据
+     *
+     * @param trade
+     * @param accessToken
+     * @param salesStoreId rst后台店铺id
+     * @return
+     */
+    private SalesOrder assembleSalesOrder(ShopOrderListItem trade, AccessToken accessToken, int salesStoreId, String accountId, String accountType) {
+        SalesOrder order = new SalesOrder();
+
+        String orderId = trade.getOrderId();
+        order.setSalesOrderId(orderId);
+        order.setSalesDealCode(orderId);
+        order.setSalesExOrderId(orderId);
+        order.setSalesDiscountMoney(trade.getPromotionAmount() == null ? 0 : trade.getPromotionAmount().intValue());
+        order.setSalesDeliver(1);
+
+        //收货人信息
+        PostAddr postAddr = trade.getPostAddr();
+        /*
+        解密信息
+        0 收件人
+        1 手机号码
+        2 详细地址
+         */
+        Map<String, String> decryptMap = new HashMap<>(3);
+        List<DecryptInfosItem> decryptInfosItems = batchDecrypt(accessToken, accountId, accountType
+                , buildCipherInfosItem(orderId, trade.getEncryptPostReceiver())
+                , buildCipherInfosItem(orderId, trade.getEncryptPostTel())
+                , buildCipherInfosItem(orderId, postAddr.getEncryptDetail()));
+        if (CollectionUtils.isNotEmpty(decryptInfosItems)) {
+            for (DecryptInfosItem decryptInfosItem : decryptInfosItems) {
+                decryptMap.put(decryptInfosItem.getCipherText(), decryptInfosItem.getDecryptText());
+            }
+        }
+        String decryptPostTel = decryptMap.get(trade.getEncryptPostTel());
+        String decryptPostReceiver = decryptMap.get(trade.getEncryptPostReceiver());
+        String decryptDetail = decryptMap.get(postAddr.getEncryptDetail());
+
+        if (CollectionUtils.isNotEmpty(decryptInfosItems)) {
+            order.setSalesOpenId(decryptPostTel);
+        }
+        order.setSalesPledgeMoney(0);
+        order.setSalesRemainDeposit(0);
+        order.setSalesOrderStatus(1);
+        order.setSalesStatus(0);
+        order.setSalesShippingStatus(0);
+        order.setSalesPayStatus(2);
+        order.setSalesProcessStatus(1);
+        order.setSalesIsSend(0);
+        order.setSalesIsLocked(0);
+        order.setSalesIsSeparate(0);
+        order.setSalesIsShip(1);
+        order.setSalesProcessRefund(0);
+        order.setSalesSendType(2);
+        order.setSalesSalesTime(new Date(trade.getCreateTime() * 1000));
+        // 地址
+        StringJoiner address = new StringJoiner(" ");
+        if (postAddr.getProvince() != null && StringUtils.isNotBlank(postAddr.getProvince().getName())) {
+            address.add(postAddr.getProvince().getName());
+        }
+        if (postAddr.getCity() != null && StringUtils.isNotBlank(postAddr.getCity().getName())) {
+            address.add(postAddr.getCity().getName());
+        }
+        if (postAddr.getTown() != null && StringUtils.isNotBlank(postAddr.getTown().getName())) {
+            address.add(postAddr.getTown().getName());
+        }
+        if (postAddr.getStreet() != null && StringUtils.isNotBlank(postAddr.getStreet().getName())) {
+            address.add(postAddr.getStreet().getName());
+        }
+        if (CollectionUtils.isNotEmpty(decryptInfosItems)) {
+            address.add(decryptDetail);
+        }
+        order.setSalesAddressInfo(address.toString());
+
+        if (CollectionUtils.isNotEmpty(decryptInfosItems)) {
+            order.setSalesAddressName(decryptPostReceiver);
+            order.setSalesAddressTel(decryptPostTel);
+        }
+        //京东不返回邮编
+        order.setSalesAddressPostcode("000000");
+        order.setSalesAmount(trade.getOrderAmount().intValue());
+        order.setSalesPayMoney(trade.getPayAmount().intValue());
+        order.setSalesPayType(getSalesPayType(trade.getPayType()));
+        order.setSalesWaitMoney(0);
+        order.setSalesShippingFee(trade.getPostAmount().intValue());
+        order.setSalesLastMoney(0);
+        order.setSalesPayTime(new Date(trade.getPayTime() * 1000));
+        order.setSalesCreateTime(new Date(trade.getCreateTime() * 1000));
+        order.setSalesAdminRemark(trade.getSellerWords());
+        order.setSalesUserRemark(trade.getBuyerWords());
+        order.setSalesCompanyId(1);
+        order.setSalesStoreId(salesStoreId);
+        order.setSalesType(1);
+        order.setSalesAddType(4);
+        order.setSalesAdminId(10135);
+        order.setSalesReturnStatus(1);
+        order.setSalesIsSublist(1);
+        order.setSalesExOrderId(trade.getOrderId());
+        order.setSalesErrorState(1);
+        order.setSalesQuality(1);
+        order.setSalesPostFirm("jd");
+        order.setSalesOrderItemList(new ArrayList<>(trade.getSkuOrderList().size()));
+
+        int warranty = 0;
+        for (SkuOrderListItem tradeOrder : trade.getSkuOrderList()) {
+            SalesOrderItem item = new SalesOrderItem();
+            //无退款状态
+            item.setItemWarrantyStatus(0);
+            if (StringUtils.isEmpty(tradeOrder.getCode())) {
+                return null;
+            }
+            // 根据后台69码查询
+            ProductColor productColor = productColorMapper.getProductColorByBar(tradeOrder.getCode());
+            if(productColor.getProductIsSplit() == 1){
+                List<ProductCombinatInfo> productCombinatList = productMapper.combinatList(productColor.getColorProductId());
+                if(productCombinatList == null || productCombinatList.size() < 1){
+                    logger.error("商城订单编号:"+productColor.getColorProductId()+"-订单项中的SKU未查询到组合产品,SKU编号:"+productColor.getColorProductId()+"; ");
+                    break;
+                }
+                int totalFeeInt = tradeOrder.getOrderAmount().intValue();
+                Integer advProductCombinatFree = totalFeeInt/productCombinatList.size();
+                for (int m = 0;m<productCombinatList.size();m++) {
+                    ProductCombinatInfo productCombinatInfo = productCombinatList.get(m);
+                    ProductColor sonPc = productColorMapper.getProductColorByBar(productCombinatInfo.getColorBar());
+                    SalesOrderItem salesOrderItem = new SalesOrderItem();
+                    item.setItemWarrantyStatus(0);
+
+                    salesOrderItem.setItemOtherId(trade.getOrderId());
+                    Integer sonNum = tradeOrder.getItemNum().intValue() * productCombinatInfo.getCombinatItemNum();
+                    //计算价格
+                    Integer itemDiscountAllFeeInt = 0;
+                    if((m+1) >= productCombinatList.size()){
+                        itemDiscountAllFeeInt = totalFeeInt;
+                    }else{
+                        itemDiscountAllFeeInt = advProductCombinatFree;
+                        totalFeeInt = totalFeeInt - itemDiscountAllFeeInt;
+                    }
+                    Integer itemDiscountFeeInt = itemDiscountAllFeeInt/sonNum;
+                    //产品市场价
+                    salesOrderItem.setItemProductPrice(itemDiscountFeeInt);
+                    //产品折扣价
+                    salesOrderItem.setItemProductDiscount(itemDiscountFeeInt);
+                    //小结
+                    salesOrderItem.setItemTotal(itemDiscountAllFeeInt);
+                    //产品数量
+                    salesOrderItem.setItemNum(sonNum);
+                    //colorBar
+                    salesOrderItem.setItemColorBar(sonPc.getColorBar());
+                    //产品id
+                    salesOrderItem.setItemProductId(sonPc.getColorProductId());
+                    salesOrderItem.setItemColorId(sonPc.getColorId());
+                    salesOrderItem.setItemProductType(sonPc.getProductType());
+                    salesOrderItem.setItemProductName(sonPc.getProductName());
+                    //产品颜色
+                    salesOrderItem.setItemProductColor(sonPc.getColorName());
+                    //商品简称
+                    salesOrderItem.setProductAbbreviation(sonPc.getProductAbbreviation());
+                    //所属产品简称
+                    salesOrderItem.setColorAbbreviation(sonPc.getColorAbbreviation());
+                    //重量
+                    salesOrderItem.setColorIsWeight(sonPc.getColorIsWeight());
+                    //是否是水机 1:水机 2;其它产品
+                    salesOrderItem.setColorIsMachine(sonPc.getColorIsMachine());
+                    //产品来源 1:产品颜色表,2:配件表
+                    salesOrderItem.setItemIsSource(1);
+                    order.getSalesOrderItemList().add(salesOrderItem);
+                }
+            } else {
+                item.setItemOtherId(trade.getOrderId());
+                item.setItemNum(tradeOrder.getItemNum().intValue());
+                item.setItemColorBar(tradeOrder.getCode());
+                item.setItemProductPrice(tradeOrder.getOrderAmount().intValue() / item.getItemNum());
+                item.setItemProductDiscount(tradeOrder.getOrderAmount().intValue() / item.getItemNum());
+                item.setItemIsSource(1);
+                item.setItemReturnNum(0);
+                //小结
+                item.setItemTotal(tradeOrder.getOrderAmount().intValue());
+                item.setItemProductId(productColor.getColorProductId());
+                item.setItemColorId(productColor.getColorId());
+                item.setItemProductType(productColor.getProductType());
+                item.setItemProductName(productColor.getProductName());
+                //产品颜色
+                item.setItemProductColor(productColor.getColorName());
+                //商品简称
+                item.setProductAbbreviation(productColor.getProductAbbreviation());
+                //所属产品简称
+                item.setColorAbbreviation(productColor.getColorAbbreviation());
+                //重量
+                item.setColorIsWeight(productColor.getColorIsWeight());
+                //是否是水机 1:水机 2;其它产品
+                item.setColorIsMachine(productColor.getColorIsMachine());
+                //产品来源 1:产品颜色表,2:配件表
+                item.setItemIsSource(1);
+                // 填充数据
+                order.getSalesOrderItemList().add(item);
+            }
+        }
+        order.setSalesWarrantyStatus(warranty);
+
+        return order;
+    }
+
+    /**
+     * 转换支付类型
+     * @param payType 【支付类型】 0、货到付款 1 、微信 2、支付宝 3、小程序 4、银行卡 5、余额 7、无需支付(0元单) 8、DOU分期(信用支付) 9、新卡支付 12、先用后付
+     * @return 1:微信支付 2:现金支付3:已支付定金¥99 4:刷卡支付 5:支付宝支付
+     */
+    private Integer getSalesPayType(Long payType) {
+        Map<Long, Integer> mapper = new HashMap<>();
+        mapper.put(1L, 1);
+        mapper.put(2L, 5);
+        Integer value = mapper.get(payType);
+
+        // 如果没有匹配上的,默认支付宝
+        if (value == null) {
+            return 5;
+        }
+
+        return value;
+    }
+
+    private CipherInfosItem buildCipherInfosItem(String orderId, String cipherText) {
+        CipherInfosItem item = new CipherInfosItem();
+        item.setCipherText(cipherText);
+        item.setAuthId(orderId);
+        return item;
+    }
+
+    /**
+     * 批量解密
+     * @param accessToken
+     */
+    private List<DecryptInfosItem> batchDecrypt(AccessToken accessToken, String accountId, String accountType, CipherInfosItem ...cipherInfosItems) {
+        OrderBatchDecryptRequest request = new OrderBatchDecryptRequest();
+        OrderBatchDecryptParam param = new OrderBatchDecryptParam();
+        param.setAccountId(accountId);
+        param.setAccountType(accountType);
+        param.setCipherInfos(Arrays.asList(cipherInfosItems));
+        request.setParam(param);
+        OrderBatchDecryptResponse response = request.execute(accessToken);
+        if ("10000".equals(response.getCode())) {
+            OrderBatchDecryptData data = response.getData();
+            if (data.getCustomErr() != null) {
+                return data.getDecryptInfos();
+            }
+        }
+        return null;
+    }
+
+}

+ 43 - 1
watero-rst-web/src/main/java/com/iamberry/rst/controllers/mq/TaobaoConfig.java

@@ -21,5 +21,47 @@ public class TaobaoConfig {
     //京东订单拉取时间间隔配置
     public static final Integer DB_JD_PULL_ORDER_LIMIT_TIME = 28;
 
-
+    //================================================== 抖音 ==================================================
+    /**
+     * 抖店AppKey
+     */
+    public static final String DOUYIN_APP_KEY = "7246651383976347193";
+    /**
+     * 抖店AppSecret
+     */
+    public static final String DOUYIN_APP_SECRET = "2613474c-6ada-4f17-b5cb-9c5a9d7c3b26";
+    /**
+     * 爱贝源小店shopid
+     */
+    public static final Long DOUYIN_IAMBERRY_SHOP_ID = 7971061L;
+    /**
+     * 美塔璞儿小店shopid
+     */
+    public static final Long DOUYIN_METAPURE_SHOP_ID = 89887499L;
+    /**
+     * 抖店订单拉取时间间隔配置
+     */
+    public static final int DB_DOUYIN_PULL_ORDER_LIMIT_TIME = 29;
+    /**
+     * 爱贝源 李杰的账号 15016721606
+     * 服务商账号体系中,商户的账户ID
+     * 用于订单敏感信息解密
+     */
+    public static final String DOUYIN_IAMBERRY_ACCOUNT_ID = "896837278237912";
+    /**
+     * 爱贝源
+     * 商户的账户ID类型;服务商账号中的主-main_account;子账号-sub_account;
+     */
+    public static final String DOUYIN_IAMBERRY_ACCOUNT_TYPE = "sub_account";
+    /**
+     * 美塔璞儿
+     * 服务商账号体系中,商户的账户ID
+     * 用于订单敏感信息解密
+     */
+    public static final String DOUYIN_METAPURE_ACCOUNT_ID = "1146105659133133";
+    /**
+     * 美塔璞儿
+     * 商户的账户ID类型;服务商账号中的主-main_account;子账号-sub_account;
+     */
+    public static final String DOUYIN_METAPURE_ACCOUNT_TYPE = "main_account";
 }

+ 57 - 0
watero-rst-web/src/main/java/com/iamberry/rst/controllers/order/AwaitSendController.java

@@ -2,8 +2,15 @@ package com.iamberry.rst.controllers.order;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.doudian.open.api.order_orderDetail.OrderOrderDetailRequest;
+import com.doudian.open.api.order_orderDetail.OrderOrderDetailResponse;
+import com.doudian.open.api.order_orderDetail.data.OrderOrderDetailData;
+import com.doudian.open.api.order_orderDetail.param.OrderOrderDetailParam;
+import com.doudian.open.core.AccessToken;
+import com.doudian.open.core.AccessTokenBuilder;
 import com.iamberry.app.tool.util.AES;
 import com.iamberry.redis.RedisUtils;
+import com.iamberry.rst.controllers.mq.DouyinTask;
 import com.iamberry.rst.controllers.mq.JingdongTask;
 import com.iamberry.rst.controllers.mq.TaobaoConfig;
 import com.iamberry.rst.controllers.mq.TaobaoTask;
@@ -115,6 +122,10 @@ public class AwaitSendController {
 
     @Autowired
     private JingdongTask jingdongTask;
+
+    @Autowired
+    private DouyinTask douyinTask;
+
     @Autowired
     private SalesOrderMapper salesOrderMapper ;
 
@@ -263,6 +274,9 @@ public class AwaitSendController {
                 } else if (temp.getSalesBatchId().startsWith("SX")) {
                     // 校验小亚通订单
                     vaildXytOrder(temp, salesOrderList);
+                } else if (temp.getSalesBatchId().startsWith("DY")) {
+                    // 校验抖音订单
+                    vaildDouyinOrder(temp, salesOrderList);
                 } else {
                     // 普通订单
                     salesOrderList.add(temp);
@@ -321,6 +335,49 @@ public class AwaitSendController {
                 .addObject("waitProductTotal", waitProductTotal);
     }
 
+    private void vaildDouyinOrder(SalesOrder temp, List<SalesOrder> salesOrderList) {
+        Integer salesStoreId = temp.getSalesStoreId();
+        Long shopId;
+        // 映射到抖音的shopId,保存的地方在DouyinTask中
+        if (salesStoreId == 148) {
+            shopId = TaobaoConfig.DOUYIN_IAMBERRY_SHOP_ID;
+        } else if (salesStoreId == 172) {
+            shopId = TaobaoConfig.DOUYIN_METAPURE_SHOP_ID;
+        } else {
+            throw new RuntimeException("未映射到抖音店铺,系统出小差啦~");
+        }
+        try {
+            AccessToken accessToken = AccessTokenBuilder.build(shopId);
+
+            OrderOrderDetailRequest request = new OrderOrderDetailRequest();
+            OrderOrderDetailParam param = new OrderOrderDetailParam();
+            param.setShopOrderId(temp.getSalesExOrderId());
+            request.setParam(param);
+            OrderOrderDetailResponse response = request.execute(accessToken);
+            if (response.isSuccess()) {
+                OrderOrderDetailData data = response.getData();
+                /*
+                https://op.jinritemai.com/docs/api-docs/15/1343
+                订单状态1 待确认/待支付(订单创建完毕)105 已支付 2 备货中 101 部分发货 3 已发货(全部发货)4 已取消5 已完成(已收货)
+                 */
+                Long orderStatus = data.getShopOrderDetail().getOrderStatus();
+                if (orderStatus == 105) {
+                    // 待发货订单
+                    salesOrderList.add(temp);
+                } else {
+                    // 订单状态异常,不允许发货
+                    syncOrderStateError(temp.getSalesId(), temp.getSalesDealCode());
+                }
+            } else {
+                LOGGER.info("请求抖音订单详情失败,OrderId: {}, 结果:{}", temp.getSalesExOrderId(), response.getMsg());
+                throw new RuntimeException("京东订单验证失败,原因:{远程调用失败!}");
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+    }
+
     private void vaildXytOrder(SalesOrder temp, List<SalesOrder> salesOrderList) {
         // 非淘宝订单 & 非淘宝订单
         if(temp.getSalesProcessRefund() != 1){

+ 133 - 0
watero-rst-web/src/test/java/junit/com/iamberry/rst/DouyinSdkTest.java

@@ -0,0 +1,133 @@
+package junit.com.iamberry.rst;
+
+import com.alibaba.fastjson.JSON;
+import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptRequest;
+import com.doudian.open.api.order_batchDecrypt.OrderBatchDecryptResponse;
+import com.doudian.open.api.order_batchDecrypt.data.DecryptInfosItem;
+import com.doudian.open.api.order_batchDecrypt.data.OrderBatchDecryptData;
+import com.doudian.open.api.order_batchDecrypt.param.CipherInfosItem;
+import com.doudian.open.api.order_batchDecrypt.param.OrderBatchDecryptParam;
+import com.doudian.open.api.order_logisticsCompanyList.OrderLogisticsCompanyListRequest;
+import com.doudian.open.api.order_logisticsCompanyList.OrderLogisticsCompanyListResponse;
+import com.doudian.open.api.order_logisticsCompanyList.param.OrderLogisticsCompanyListParam;
+import com.doudian.open.api.order_orderDetail.OrderOrderDetailRequest;
+import com.doudian.open.api.order_orderDetail.OrderOrderDetailResponse;
+import com.doudian.open.api.order_orderDetail.param.OrderOrderDetailParam;
+import com.doudian.open.api.order_searchList.OrderSearchListRequest;
+import com.doudian.open.api.order_searchList.OrderSearchListResponse;
+import com.doudian.open.api.order_searchList.param.CombineStatusItem;
+import com.doudian.open.api.order_searchList.param.OrderSearchListParam;
+import com.doudian.open.core.AccessToken;
+import com.doudian.open.core.AccessTokenBuilder;
+import com.doudian.open.core.GlobalConfig;
+import com.iamberry.rst.controllers.mq.TaobaoConfig;
+import com.iamberry.wechat.tools.DateTimeUtil;
+import com.iamberry.wechat.tools.payUtil.DatetimeUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author xuyongjun
+ * @since 2023-06-21
+ */
+public class DouyinSdkTest {
+    String token;
+
+    @Before
+    public void setup() {
+        GlobalConfig.initAppKey(TaobaoConfig.DOUYIN_APP_KEY);
+        GlobalConfig.initAppSecret(TaobaoConfig.DOUYIN_APP_SECRET);
+        token = "991a9b25-e0b6-471d-8040-76fbc33d091d";
+    }
+
+    @Test
+    public void testGetAccessToken() {
+
+        //入参为shopId
+//        AccessToken accessToken = AccessTokenBuilder.build(TaobaoConfig.DOUYIN_METAPURE_SHOP_ID); //123456是shopId
+//        System.out.println(accessToken.getAccessToken());
+        // 美塔璞儿 991a9b25-e0b6-471d-8040-76fbc33d091d
+//        // 测试店铺
+//        String token = "aa10210e-24c4-4f59-99b2-0b3ef93435be";
+//        // 爱贝源小店
+//        String token = "2c7a8fa1-694b-4c6f-96d9-ae1c574866d8";
+        OrderSearchListRequest request = new OrderSearchListRequest();
+        OrderSearchListParam param = new OrderSearchListParam();
+        param.setPage(0L);
+        param.setSize(1L);
+        List<CombineStatusItem> combineStatusItems = new ArrayList<>();
+        CombineStatusItem combineStatusItem = new CombineStatusItem();
+        combineStatusItem.setOrderStatus("105,2"); // 已付款和待发货
+        combineStatusItems.add(combineStatusItem);
+        param.setCombineStatus(combineStatusItems);
+        param.setCreateTimeStart(DatetimeUtil.parseTime("2023-05-01 00:00:00").getTime() / 1000);
+        param.setCreateTimeEnd(new Date().getTime() / 1000);
+        request.setParam(param);
+        OrderSearchListResponse response = request.execute(AccessTokenBuilder.parse(token));
+        System.out.println(response.getLogId());
+        System.out.println(response.getData());
+    }
+
+    @Test
+    public void testDecrypt() {
+        CipherInfosItem item = new CipherInfosItem();
+//        item.setAuthId("6919832410777065086");
+//        item.setCipherText("$$8ld5JAAZ52xoFSJ7XwYYySBOcFJeSHM4xOj9pLwnu+JL47pfexhc/3V/yc4bfGiQbzalSWJ3qFYkJ+4HR8BUuFHDpv4mp3BIefkCCFjJMctM*CgkIARCtHCABKAESPgo84fc0xR73u6FCwJTqhryAe4tU000OJUAS8YZQCUQTQGZM4naB05qLnWw11eWSXEWucxmcWGBJIgGsV/xBGgA=$1$$");
+//        System.out.println(decryptInfosItems);
+//        com.doudian.open.api.order_batchSensitive.param.CipherInfosItem item = new com.doudian.open.api.order_batchSensitive.param.CipherInfosItem();
+        item.setAuthId("6919848611052655995");
+        item.setCipherText("##IR4ddyeiIGMOtWZq6rUgC0VCZgvxRzbsc7knRETbAOR7DkmD59G52HtXHK+TX9yjvIb4EBKm6c3mNBpTfnD5by19ljgPiSiiAcVxIewj+kO9kpX20Qx0qMw4+Kg=*CgkIARCtHCABKAESPgo8FUcUr3LHoF6UbgrZyEvT1hzbmKOwCtRSKp4bm6YYd7rvBxOAi8etBkAyCxHLhosWYf+gFhq/zxvk81n6GgA=#1##");
+        List<DecryptInfosItem> decryptInfosItems = batchDecrypt(AccessTokenBuilder.parse(token), item);
+//        List<com.doudian.open.api.order_batchSensitive.data.DecryptInfosItem> decryptInfosItems = batchSensitive(AccessTokenBuilder.parse(token), item);
+        System.out.println(decryptInfosItems);
+    }
+    private List<DecryptInfosItem> batchDecrypt(AccessToken accessToken, CipherInfosItem...cipherInfosItems) {
+        OrderBatchDecryptRequest request = new OrderBatchDecryptRequest();
+        OrderBatchDecryptParam param = new OrderBatchDecryptParam();
+        param.setAccountId(TaobaoConfig.DOUYIN_METAPURE_ACCOUNT_ID);
+        param.setAccountType(TaobaoConfig.DOUYIN_IAMBERRY_ACCOUNT_TYPE);
+        param.setCipherInfos(Arrays.asList(cipherInfosItems));
+        request.setParam(param);
+        OrderBatchDecryptResponse response = request.execute(accessToken);
+        if ("10000".equals(response.getCode())) {
+            OrderBatchDecryptData data = response.getData();
+            if (data.getCustomErr() != null) {
+                return data.getDecryptInfos();
+            }
+        }
+        return null;
+    }
+
+    @Test
+    public void testGetOrderDetail() {
+        OrderOrderDetailRequest request = new OrderOrderDetailRequest();
+        OrderOrderDetailParam param = new OrderOrderDetailParam();
+        param.setShopOrderId("6919512310210303803");
+        request.setParam(param);
+        OrderOrderDetailResponse response = request.execute(AccessTokenBuilder.parse(token));
+        System.out.println(response.getLogId());
+        System.out.println(response.getData());
+    }
+
+    /**
+     * 获取快递公司列表
+     */
+    @Test
+    public void testGetLogisticsCompanyList() {
+        OrderLogisticsCompanyListParam param = new OrderLogisticsCompanyListParam();
+        OrderLogisticsCompanyListRequest request = new OrderLogisticsCompanyListRequest();
+        request.setParam(param);
+        OrderLogisticsCompanyListResponse response = request.execute(AccessTokenBuilder.parse(token));
+        System.out.println(JSON.toJSONString(response.getData()));
+    }
+
+    @Test
+    public void testTime() {
+        System.out.println(DateTimeUtil.format(DateTimeUtil.addDay(-20), "yyyy-MM-dd HH:mm:ss"));
+    }
+}