java对接旺店通数据同步

添加配置文件

erp:
  url: http://api.wangdian.cn/xxxx/
  sid: xxxx
  appkey: xxxx
  appsecret: xxxxxxxxxxxxxxxxxxxxx
  shopNo: 'xx'

@Data
@Configuration
@ConfigurationProperties(prefix = "erp")
public class ErpConfig {
    String url;
    String sid;
    String appkey;
    String appsecret;
    String shopNo;
}    

业务实现

/**
 * 推送订单到旺店通服务
 */
@Slf4j
@Component("wdtOrderLogisticsSyncTask")
@AllArgsConstructor
public class WdtOrderLogisticsSyncTask {

    @Autowired
    private DeliveryService deliveryService;

    @Autowired
    private DeliveryOrderService deliveryOrderService;

    @Autowired
    private final OrderItemService orderItemService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private final SysConfigMapper sysConfigMapper;


    //测试环境
    private final String baseUrl = "https://sandbox.wangdian.cn/openapi2/";
    //物流同步查询
    private final String logisticsSyncQuery = "logistics_sync_query.php";
    //物流同步回写
    private final String logisticsSyncAck = "logistics_sync_ack.php";


    /**
     * 获取物流待同步的订单
     */
    public String wdtOrderLogisticsTask() {
        log.info("------- 推送订单到旺店通服务 ----> 时间:" + DateUtils.dateToString(new Date()));
        SysConfig wdtParamKey = sysConfigMapper.queryByKey("WDT_PARAM_KEY");
        if(Validator.isEmpty(wdtParamKey) || Validator.isEmpty(wdtParamKey.getParamValue())){
            log.error("====== 推送订单到旺店通失败,旺店通账户参数配置异常!======>>>> ");
            return "";
        }
        Map<String,String> wdtParam = FastJsonHelper.stringToCollect(wdtParamKey.getParamValue());

        //查询所有的未推送 且待发货状态的订单列表
        String responseStr = selectLogisticsWdt(wdtParam);
        //解析响应参数
        JSONObject stringToMap = JSONObject.parseObject(responseStr);
        //状态码:0表示成功,其他表示失败
        if(!Validator.equal(stringToMap.get("code").toString(),"0")){
            log.error("====== 查询旺店通物流信息同步接口请求错误 ======>>>> 旺店通返回信息:{}",responseStr);
            return responseStr;
        }else {
            log.info("====== 查询旺店通物流信息同步接口请求成功 ======>>>> {}",responseStr);
            //设置订单发货
            List<TreeMap<String, String>> logisticsList = orderDelivery(stringToMap);
            if(logisticsList.size() == 0){
                log.info("====== 旺店通物流信息同步完成,暂无订单信息需要同步。 ======>>>>");
                return "";
            }
            //物流同步回写请求参数
            TreeMap<String,String> mapParam = new TreeMap<>();
            mapParam.put("logistics_list",FastJsonHelper.toJSONString(logisticsList));
            //请求旺店通 物流同步回写 接口
            String responseSyncStr = logisticsSyncAckWdt(mapParam,wdtParam);
            //解析响应参数
            JSONObject responseSyncMap = JSONObject.parseObject(responseSyncStr);
            //状态码:0表示成功,其他表示失败
            if(Validator.equal(responseSyncMap.get("code").toString(),"0")){
                log.info("====== 旺店通物流信息同步回写接口请求成功 ======>>>>");
            }else {
                log.error("====== 旺店通物流信息同步回写接口请求失败 ======>>>> 旺店通返回信息:{}",responseSyncStr);
            }
            return responseSyncStr;
        }
    }

    /**
     * 解析旺店通物流同步返回数据并处理本地本地订单发货
     * @param jsonObject
     */
    private List<TreeMap<String,String>>  orderDelivery(JSONObject jsonObject) {
        List<LogisticsSyncVO> trades = FastJsonHelper.toList(jsonObject.get("trades").toString(), LogisticsSyncVO.class);
        if(Validator.isEmpty(trades)){
            return new ArrayList<>();
        }
        //同步成功的物流回写列表
        List<TreeMap<String,String>> logisticsList = new ArrayList<>();
        //遍历待同步的物流信息
        for (LogisticsSyncVO trade : trades) {
            //单个物流同步回写订单信息
            TreeMap<String,String> logisticsSyncAckParam = new TreeMap<>();
            //回写的记录id
            logisticsSyncAckParam.put("rec_id",trade.getRec_id());
            //判断是否已发货
            Order order = orderService.getOrderByOrderNumber(trade.getTid());
            if(Validator.isNotEmpty(order)){
                //订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败 7:待成团
                if(!Validator.equal(order.getStatus(),2)){
                    //如果当前订单不是代发货状态  回调旺店通 通知下次不用发送该订单
                    //回写状态   回写状态: 0成功 1失败
                    logisticsSyncAckParam.put("status","0");
                    //保存到已更新列表里
                    logisticsList.add(logisticsSyncAckParam);
                    continue;
                }
            }else {
                // 如果该订单查询不到 则跳过本次循环
                // 回调旺店通 通知下次不用发送该订单
                logisticsSyncAckParam.put("status","0");
                //保存到已更新列表里
                logisticsList.add(logisticsSyncAckParam);
                continue;
            }
            //获取物流类型 具体类型详见 旺铺通-API文档-物流代码表
            String logisticsType = trade.getLogistics_type();
            //查询本地物流表是否有该物流信息
            Delivery delivery = deliveryService.getOne(Wrappers.<Delivery>lambdaQuery().eq(Delivery::getLogisticsType, logisticsType).last(" LIMIT 1 "));
            //如果是空 则添加一条该物流信息
            if(Validator.isEmpty(delivery)){
                delivery = new Delivery();
                delivery.setLogisticsType(logisticsType);//类型
                delivery.setDvyName(trade.getLogistics_name());//物流名字
                //保存该条物流信息
                deliveryService.save(delivery);
            }
            //组装订单物流信息
            DeliveryOrderItemParam deliveryOrderParam = new DeliveryOrderItemParam();
            deliveryOrderParam.setOrderNumber(trade.getTid());
            deliveryOrderParam.setDvyId(delivery.getDvyId());
            deliveryOrderParam.setDvyFlowId(trade.getLogistics_no());
            // 1-自己联系快递  3-无需快递  4-同城配送
            deliveryOrderParam.setDeliveryType(1);
            List<OrderItem> orderItemsByOrderNumber = orderItemService.getOrderItemsByOrderNumber(trade.getTid(), 1);
            deliveryOrderParam.setSelectOrderItems(orderItemsByOrderNumber);
            //设置是旺店通发货标识
            deliveryOrderParam.setIsWdt(1);
            //捕捉异常防止全部更新失败
            try {
                //发货操作
                deliveryOrderService.saveDeliveriesInfo(deliveryOrderParam);
                //回写状态   回写状态: 0成功 1失败
                logisticsSyncAckParam.put("status","0");
            }catch (Exception e){
                log.error("====== 订单物流同步本地更新失败,订单号:{}  ======>>>> 错误信息:{}",trade.getTid(),e);
                //回写状态   回写状态: 0成功 1失败
                logisticsSyncAckParam.put("status","1");
            }
            //保存到已更新列表里
            logisticsList.add(logisticsSyncAckParam);
        }
        return logisticsList;
    }

    /**
     * 查询旺店通物流同步  PS:后台发货接口:/orderItemsDelivery
     * @return
     */
    public String selectLogisticsWdt(Map<String,String> wdtParam) {
        log.info("进入查询旺店通物流同步通方法============>>>>>>> 时间:" + DateUtils.dateToString(new Date()));
        try {
            TreeMap<String,String> mapParam = new TreeMap();
            //构建请求参数
            //获取条数
            mapParam.put("limit","50");
            //店铺编号
            mapParam.put("shop_no",wdtParam.get("shop_no"));//wdtParam.get()
            //构建请求对象
            WdtClient client = new WdtClient(wdtParam.get("sid"), wdtParam.get("appkey"), wdtParam.get("appsecret"), wdtParam.get("baseUrl"));
            // 发送HTTP请求...
            String response = client.execute(logisticsSyncQuery, mapParam);
            //格式化解析响应参数
            String responseStr = UnicodeUtil.toString(response);
            log.info("============ 查询旺店通物流同步请求结果响应 ===========>>>>>>>>>>>> {}",responseStr);
            return responseStr;
        }catch (Exception e){
            log.error("====== 查询旺店通物流同步失败 ======>>>> 信息:{} ------->>>>:{}",e.getMessage());
        }
        return "";
    }

    /**
     * 旺店通物流同步回写
     * @param mapParam 参数信息
     * @return
     */
    public String logisticsSyncAckWdt(TreeMap<String,String> mapParam,Map<String,String> wdtParam) {
        try {
            //构建请求对象
            WdtClient client = new WdtClient(wdtParam.get("sid"), wdtParam.get("appkey"), wdtParam.get("appsecret"), wdtParam.get("baseUrl"));
            // 发送HTTP请求...
            String response = client.execute(logisticsSyncAck, mapParam);
            //格式化解析响应参数
            String responseStr = UnicodeUtil.toString(response);
            return responseStr;
        }catch (Exception e){
            log.error("====== 查询旺店通物流同步失败 ======>>>> 信息:{} ------->>>>:{}",e.getMessage());
        }
        return "";
    }


    /**
     * 手动订单发货 !!临时方法
     */
    @Transactional(rollbackFor = Exception.class)
    public void  manualOrderShipment(){
        List<OrderLogistics> orderLogistics = orderService.queryAllOrderLogistics();
        log.error("======= 查询到需要手动发货的订单数量:{}条 ======>>>>",orderLogistics.size());
        if(orderLogistics.size() == 0){
            log.error("======= 暂未查询到需要手动发货的订单 ======>>>>");
            return;
        }
        //待发货订单数据列表
        List<DeliveryOrderItemParam> orderItemParams = new ArrayList<>();
        //遍历所有信息
        for (OrderLogistics orderLogistic : orderLogistics) {

            if(Validator.isEmpty(orderLogistic.getOrderNumber())){
                continue;
            }
            //是否是多个订单
            if(!orderLogistic.getOrderNumber().contains(";")){
                //判断是否已发货
                Order order = orderService.getOrderByOrderNumber(orderLogistic.getOrderNumber());
                if(Validator.isEmpty(order)){
                    continue;
                }
                //订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败 7:待成团
                if(!Validator.equal(order.getStatus(),2)){
                    continue;
                }
                //获取物流类型 具体类型详见 旺铺通-API文档-物流代码表
                String logisticsName = orderLogistic.getLogisticsName();
                //查询本地物流表是否有该物流信息
                Delivery delivery = deliveryService.getOne(Wrappers.<Delivery>lambdaQuery().eq(Delivery::getDvyName, logisticsName).last(" LIMIT 1 "));
                //如果是空 则添加一条该物流信息
                if(Validator.isEmpty(delivery)){
                    delivery = new Delivery();
                    delivery.setLogisticsType("");//类型
                    delivery.setDvyName(logisticsName);//物流名字
                    //保存该条物流信息
                    deliveryService.save(delivery);
                }
                //组装订单物流信息
                DeliveryOrderItemParam deliveryOrderParam = new DeliveryOrderItemParam();
                deliveryOrderParam.setOrderNumber(orderLogistic.getOrderNumber());
                deliveryOrderParam.setDvyId(delivery.getDvyId());
                deliveryOrderParam.setDvyFlowId(orderLogistic.getLogisticsNumber());
                // 1-自己联系快递  3-无需快递  4-同城配送
                deliveryOrderParam.setDeliveryType(1);
                List<OrderItem> orderItemsByOrderNumber = orderItemService.getOrderItemsByOrderNumber(orderLogistic.getOrderNumber(), 1);
                deliveryOrderParam.setSelectOrderItems(orderItemsByOrderNumber);
                //设置是旺店通发货标识
                deliveryOrderParam.setIsWdt(1);
                //保存到集合里
                orderItemParams.add(deliveryOrderParam);
            }else {
                //存在多个订单
                List<String> orderNumbers = Arrays.asList(orderLogistic.getOrderNumber().split(";"));
                if(Validator.isEmpty(orderNumbers)){
                    continue;
                }
                //获取物流类型 具体类型详见 旺铺通-API文档-物流代码表
                String logisticsName = orderLogistic.getLogisticsName();
                //查询本地物流表是否有该物流信息
                Delivery delivery = deliveryService.getOne(Wrappers.<Delivery>lambdaQuery().eq(Delivery::getDvyName, logisticsName).last(" LIMIT 1 "));
                //如果是空 则添加一条该物流信息
                if(Validator.isEmpty(delivery)){
                    delivery = new Delivery();
                    delivery.setLogisticsType("");//类型
                    delivery.setDvyName(logisticsName);//物流名字
                    //保存该条物流信息
                    deliveryService.save(delivery);
                }

                //遍历订单编号列表
                numberIds : for (String number : orderNumbers) {
                    //判断是否已发货
                    Order order = orderService.getOrderByOrderNumber(number);
                    if(Validator.isEmpty(order)){
                        continue numberIds;
                    }
                    //订单状态 1:待付款 2:待发货 3:待收货 4:待评价 5:成功 6:失败 7:待成团
                    if(!Validator.equal(order.getStatus(),2)){
                        continue numberIds;
                    }
                    //组装订单物流信息
                    DeliveryOrderItemParam deliveryOrderParam = new DeliveryOrderItemParam();
                    deliveryOrderParam.setOrderNumber(number);
                    deliveryOrderParam.setDvyId(delivery.getDvyId());
                    deliveryOrderParam.setDvyFlowId(orderLogistic.getLogisticsNumber());
                    // 1-自己联系快递  3-无需快递  4-同城配送
                    deliveryOrderParam.setDeliveryType(1);
                    List<OrderItem> orderItemsByOrderNumber = orderItemService.getOrderItemsByOrderNumber(number, 1);
                    deliveryOrderParam.setSelectOrderItems(orderItemsByOrderNumber);
                    //设置是旺店通发货标识
                    deliveryOrderParam.setIsWdt(1);
                    //保存到集合里
                    orderItemParams.add(deliveryOrderParam);
                }
            }
        }
        log.info("================待手动发货订单共计:{} 个=============>>>>>>>>>>",orderItemParams.size());

        //发货操作
        for (DeliveryOrderItemParam orderItemParam : orderItemParams) {
            deliveryOrderService.saveDeliveriesInfo(orderItemParam);
        }


    }

}

旺店物流同步进阶版

由于业务原因 一个回传的物流字段是多个子物流单号拼接起来的 这个时候同步回传就不适用了 同步回传会把下面的子订单号给回传掉 旺店通会默认将当前订单默认为已处理掉的

@Slf4j
@Component("erpTask")
public class ErpInfoTask {
    @Autowired
    ErpConfig erpConfig;
    @Autowired
    ITbOrderService orderService;
    @Autowired
    JedisClusterUtils jedisClusterUtils;
    //测试环境
    private final String baseUrl = "https://sandbox.wangdian.cn/openapi2/";
    //查询销售出库单
    private final String stockoutOrderQuery = "stockout_order_query_trade.php";

    private final String COUNT = "Erp_Info_Task_Count";

    private final String TIME = "ERP_PAGE_TIME";

    private final String TIME_END = "ERP_PAGE_TIME_END";

    private final String format = "yyyy-MM-dd HH:mm:ss";

    public void getErpInfoTask() {
        getStockoutOrder(0);
    }

    public void getStockoutOrder(int i) {
        WdtClient client = new WdtClient(erpConfig.getSid(), erpConfig.getAppkey(), erpConfig.getAppsecret(), erpConfig.getUrl());
        Map<String, String> params = new HashMap<>();
        // 设置开始结束时间
        Date date = new Date();
        String begin = null;
        if(StringUtils.isBlank(jedisClusterUtils.getString(TIME))) {
            // 第一次启动 从前一天查看
            begin = DateUtil.format(DateUtil.offsetDay(DateUtil.beginOfDay(date),-1), this.format);
        }else if (DateUtil.hour(date, true) == 17 && DateUtil.minute(date) <= 10 && DateUtil.minute(date) > 0 && i == 0){
            // 到今日发货时间 查今日所有
            begin = DateUtil.format(DateUtil.offsetDay(DateUtil.beginOfDay(date),-2), this.format);
        } else {
            // 正常执行走上一次查询结束时间
            begin = jedisClusterUtils.getString(TIME);
        }

        // 初始值 选用当前时间
        String end = null;
        if(StringUtils.isBlank(jedisClusterUtils.getString(TIME_END))){
           end = DateUtil.format(new Date(), this.format);
        }else {
            end = jedisClusterUtils.getString(TIME_END);
        }

        int size = 50;
        // 设置参数 查询当天的 已发货的
        params.put("shop_no", erpConfig.getShopNo());
        params.put("start_time", begin);
        params.put("end_time", end);
        params.put("page_size", Integer.toString(size));
        params.put("page_no", Integer.toString(i));
        params.put("status", "95");

        // 发送请求
        try {
            String execute = client.execute(stockoutOrderQuery, params);
            ErpOrderResult orderResult = JSONObject.parseObject(execute, ErpOrderResult.class);
            if (orderResult.getCode() == 0) {
                if (i == 0) {
                // 分页总条数
                Integer count = orderResult.getTotalCount();
                // 剩余调用次数
                Integer pageCount = (count / 50) + 1;

                if (pageCount > 0) {
                        jedisClusterUtils.deleteKey(COUNT);
                        jedisClusterUtils.incrby(COUNT, pageCount);
                    }
                }

                List<StockoutList> stockoutList = orderResult.getStockoutList();
                if (CollUtil.isEmpty(stockoutList)) {
                    log.info("====== 暂无出库订单信息 ======>>>>");
                    // 更新每次分页请求时间 保证下一次开始时间的连贯性
                    jedisClusterUtils.saveString(TIME,end);
                    // 查询次数用完移除分页结束时间
                    jedisClusterUtils.deleteKey(TIME_END);
                } else {
                    log.info("====== 订单信息 ======");
                    for (StockoutList list : stockoutList) {
                        log.info("list===>>>:{}", list);
                        // 根据单号查询数据
                        log.info("====== 订单已发货 ======");
                        StringBuilder no = new StringBuilder();
                        TbOrder tbOrder = orderService.selectTbOrderById(list.getSrcTradeNo());

                        log.info("tbOrder===>>>:{}", tbOrder);
                        log.info("物流单号===>>>:{}", list.getLogisticsNo());

                        if (StringUtils.isBlank(tbOrder.getSendOutBill())) {
                            no.append(list.getLogisticsNo());
                        } else {
                            // 不包含就拼接
                            if (!tbOrder.getSendOutBill().contains(list.getLogisticsNo())) {
                                no.append(tbOrder.getSendOutBill()).append(",").append(list.getLogisticsNo());
                            } else {
                                continue;
                            }
                        }
                        if (no.length() > 0
                                && !"null".equals(no.toString())
                                && !"".equals(no.toString())) {
                            log.info("更新{}订单物流===>>>:{}", no, list.getLogisticsNo());
                            orderService.updateErpSendOutBill(no.toString(), list.getSrcTradeNo());
                        }
                    }
                    // 调用分页
                    if (jedisClusterUtils.decrby(COUNT, 1) > 0) {
                        if(i == 0) {
                            // 保证这一批次时间的一直性 结束时间按照第一次的请求时间
                            jedisClusterUtils.saveString(TIME_END,end);
                        }
                        log.info("count=====>>>{}",jedisClusterUtils.getString(COUNT));
                        getStockoutOrder(i+1);
                    }else {
                        // 更新每次分页请求时间 保证下一次开始时间的连贯性
                        jedisClusterUtils.saveString(TIME,end);
                        // 查询次数用完移除分页结束时间
                        jedisClusterUtils.deleteKey(TIME_END);
                    }
                }
            } else {
                log.info("======查询失败======>>>{}", orderResult.getMessage());
            }

        } catch (IOException e) {
            log.info("====请求旺店通查询销售出库单接口失败===>>{}", e.getMessage());
        }
    }
}
Java是一种广泛应用于软件开发的编程语言,具备强大的跨平台性和易于学习的特点。在对接PLC读写复杂数据S7方面,Java也提供了丰富的支持和解决方案。 首先,Java提供了一些成熟的库和框架,如S7comm和S7J API,可以帮助开发人员直接与PLC信。这些库和框架提供了丰富的函数和方法,可以实现与PLC的数据信、读取和写入等操作。开发人员可以根据具体的需求和PLC的信协议选择适合的库和框架。 其次,Java提供了强大的网络编程支持,可以过TCP/IP协议与PLC建立连接并进行信。过建立Socket连接,开发人员可以使用Java提供的输入输出流读取和写入PLC数据。可以根据PLC的信规范和数据结构,将Java中的数据类型与PLC中的数据类型进行映射,实现复杂数据的读取和写入。 此外,Java还提供了一些处理二进制数据的辅助类和方法,如ByteBuffer等,可以方便地进行数据类型转换和字节序列操作。过这些工具和方法,开发人员可以处理PLC中的复杂数据类型,如数组、结构体和定点数等。 最后,Java还支持多线程编程,可以过多线程实现对PLC的并发读写操作。这对于需要高效处理大量数据或实时控制的应用特别有用。 综上所述,Java对接PLC读写复杂数据S7提供了丰富的支持和解决方案。开发人员可以利用Java提供的库、框架和网络编程支持,实现与PLC的数据信、读写等操作。同时,过处理二进制数据和多线程编程,可以方便地实现对PLC中复杂数据的处理。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dotclv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值