package com.hys.app.service.kuaidiniao; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.digest.DigestUtil; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.hys.app.converter.erp.OrderConverter; import com.hys.app.framework.context.user.AdminUserContext; import com.hys.app.framework.database.BaseQueryParam; import com.hys.app.framework.exception.ServiceException; import com.hys.app.framework.util.BeanUtils; import com.hys.app.framework.util.ScriptUtil; import com.hys.app.mapper.erp.KdnMapper; import com.hys.app.mapper.goods.ProductMapper; import com.hys.app.model.erp.dos.*; import com.hys.app.model.erp.enums.*; import com.hys.app.service.erp.*; import com.hys.app.service.kuaidiniao.entity.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.net.URLEncoder; import java.time.LocalDateTime; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; @Service public class KuaiDiNiaoServiceImpl implements KuaiDiNiaoService { /** * 快递鸟apiId */ @Value("${kuaidianiao.id}") private String id; /** * 快递鸟apiKey */ @Value("${kuaidianiao.key}") private String apiKey; /** * 快递鸟请求地址 */ @Value("${kuaidianiao.apiUrl}") private String url; /** * 快递鸟apiId */ @Value("${kuaidianiao.kuaidi.id}") private String kuaiDiId; /** * 快递鸟apiKey */ @Value("${kuaidianiao.kuaidi.key}") private String kuaiDiKey; /** * 快递鸟请求地址 */ @Value("${kuaidianiao.kuaidi.apiUrl}") private String kuaiDiUrl; @Autowired private OrderSendManager orderSendManager; @Autowired private OrderManager orderManager; @Autowired private OrderConverter converter; @Autowired private KdnMapper kdnMapper; private static final Logger log = LoggerFactory.getLogger(ScriptUtil.class); @Override public String kdShip(PreOrderModelDTO preOrderModel, Long orderId, AddressDTO addressDTO) { preOrderModel.setOrderCode(IdUtil.fastUUID()); fillParam(preOrderModel); PreOrderModel model = BeanUtil.copyProperties(preOrderModel, PreOrderModel.class); String kdnCode = sendUrl(JSONUtil.toJsonStr(model)); if (StrUtil.isNotEmpty(kdnCode)) { //如果快递鸟下单成功保存 快递信息 OrderSendDO aDo = orderSendManager.getById(orderId); log.info("快递鸟下单成功 我们的订单号:---------------------" + orderId); converter.copyProperties(aDo, preOrderModel, preOrderModel.getReceiver(), preOrderModel.getSender()); aDo.setGoodsList(preOrderModel.getGoodsList()); aDo.setKdnOrderCode(kdnCode); aDo.setSendAddress(addressDTO.getSendAddress()); aDo.setReceiveAddress(addressDTO.getReceiveAddress()); orderSendManager.updateById(aDo); } return kdnCode; } @Override public void createStore(CreateStoreModel createStoreModel, String constants) { if (Pattern.matches(".*[\\u4e00-\\u9fa5\\p{P}].*", createStoreModel.getStoreCode())){ throw new ServiceException("门店编码和统一社会信用代码不能包含中文和特殊符号"); } if (Pattern.matches(".*[\\u4e00-\\u9fa5\\p{P}].*", createStoreModel.getCreditCode())){ throw new ServiceException("门店编码和统一社会信用代码不能包含中文和特殊符号"); } Long modelId = createStoreModel.getId(); createStoreModel.setId(null); fillParam(createStoreModel); CreateStoreModel2 createStoreModel2 = BeanUtil.copyProperties(createStoreModel, CreateStoreModel2.class); try { String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(createStoreModel2) + apiKey)), "UTF-8"); System.out.println("创建店铺签名--------------------------------------" + design); //拼接参数 String param = "interfaceType=" + constants + "&customerCode=" + id + "&requestData=" + JSONUtil.toJsonStr(createStoreModel2) + "&dataSign=" + design; //发请求 String res = HttpUtil.post(url, param); Map map = JSON.parseObject(res, Map.class); if (ObjectUtil.isNotNull(map.get("resultCode")) && !(100 == Integer.parseInt(map.get("resultCode").toString()))) { throw new ServiceException("店铺创建失败" + map.get("reason").toString()); } Map dataMap = JSON.parseObject(JSON.toJSONString(map.get("data")), Map.class); createStoreModel.setKdnStoreCode(dataMap.get("kdnStoreCode").toString()); if (ObjectUtil.isNotNull(modelId)) { createStoreModel.setId(modelId); kdnMapper.updateById(createStoreModel); } else { kdnMapper.insert(createStoreModel); } } catch (Exception e) { e.printStackTrace(); throw new ServiceException("店铺创建异常"); } } @Override public Page getStoreList(BaseQueryParam baseQueryParam) { return kdnMapper.selectPage(new Page<>(baseQueryParam.getPageNo(), baseQueryParam.getPageSize()), new LambdaQueryWrapper<>()); } @Override public void selectAudit(CreateStoreModel createStoreModel) { Map hashMap = new HashMap<>(); hashMap.put("storeCode", createStoreModel.getStoreCode()); try { String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(hashMap) + apiKey)), "UTF-8"); System.out.println("获取门店状态签名--------------------------------------" + design); //拼接参数 String param = "interfaceType=" + KdConstants.queryStoreStatus + "&customerCode=" + id + "&requestData=" + JSONUtil.toJsonStr(hashMap) + "&dataSign=" + design; //发请求 String res = HttpUtil.post(url, param); Map map = JSON.parseObject(res, Map.class); if (ObjectUtil.isNotNull(map.get("resultCode")) && !(100 == Integer.parseInt(map.get("resultCode").toString()))) { throw new ServiceException("请求状态失败" + map.get("reason").toString()); } Map dataMap = JSON.parseObject(JSON.toJSONString(map.get("data")), Map.class); List storeDetail = JSON.parseArray(dataMap.get("storeDetail").toString(), Map.class); for (Map statusMap : storeDetail) { switch (statusMap.get("intraCode").toString()) { case "SS": createStoreModel.setSsStatus(Integer.parseInt(statusMap.get("storeStatus").toString())); if (ObjectUtil.isNotNull(statusMap.get("operationFailReason"))){ createStoreModel.setFnReason(statusMap.get("operationFailReason").toString()); } case "DD": createStoreModel.setDdStatus(Integer.parseInt(statusMap.get("storeStatus").toString())); if (ObjectUtil.isNotNull(statusMap.get("operationFailReason"))){ createStoreModel.setFnReason(statusMap.get("operationFailReason").toString()); } case "FN": createStoreModel.setFnStatus(Integer.parseInt(statusMap.get("storeStatus").toString())); if (ObjectUtil.isNotNull(statusMap.get("operationFailReason"))){ createStoreModel.setFnReason(statusMap.get("operationFailReason").toString()); } case "MTPS": createStoreModel.setMtStatus(Integer.parseInt(statusMap.get("storeStatus").toString())); if (ObjectUtil.isNotNull(statusMap.get("operationFailReason"))){ createStoreModel.setFnReason(statusMap.get("operationFailReason").toString()); } } } kdnMapper.updateById(createStoreModel); } catch (Exception e) { e.printStackTrace(); throw new ServiceException("请求发生异常"); } } /** * 订阅就行了,订阅成功与否均不影响货物的正常派发 */ @Override public void queryLogistics(LogisyicsTopic logisyicsTopic) { try { String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(logisyicsTopic) + kuaiDiKey)), "UTF-8"); Map paramMap = new HashMap<>(); paramMap.put("RequestData", JSONUtil.toJsonStr(logisyicsTopic)); paramMap.put("DataType", 2); paramMap.put("EBusinessID", kuaiDiId); paramMap.put("DataSign", design); paramMap.put("RequestType", KdConstants.orderLogistics); String res = HttpUtil.post(kuaiDiUrl, paramMap); log.info(logisyicsTopic.getLogisticCode() + "快递鸟轨迹订阅" + res); } catch (Exception e) { } } @Override public Boolean kdnReturnBackLogistics(Map map) { try { OrderSendDO sendDO = orderSendManager.getOne(new LambdaQueryWrapper().eq(OrderSendDO::getLogisticsCode, map.get("LogisticCode").toString()).last("limit 1")); if (ObjectUtil.isNotNull(sendDO)) { List maps = JSON.parseArray(JSON.toJSONString(map.get("Traces")), Map.class); sendDO.setLogistics(maps); } orderSendManager.updateById(sendDO); return true; }catch (Exception e){ return false; } } @Override public String prePareTime(PreOrderModelDTO preOrderModel, Long orderId, AddressDTO addressDTO) { return null; } /** * @param dataJson 业务参数 * @return 返回JSON */ private String sendUrl(String dataJson) { String design =""; try { design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(dataJson + apiKey)), "UTF-8"); }catch (Exception e){ throw new ServiceException("签名异常"); } System.out.println("--------------------------------------" + design); //拼接参数 String param = "interfaceType=" + KdConstants.preOrder + "&customerCode=" + id + "&requestData=" + dataJson + "&dataSign=" + design; //发请求 String res = HttpUtil.post(url, param); Map map = JSON.parseObject(res, Map.class); //resultCode == 100表示预下单成功,预下单郑工后立马调用下单接口 if (ObjectUtil.isNotNull(map.get("resultCode")) && 100 == Integer.valueOf(map.get("resultCode").toString())) { //拼接参数 String createParam = "interfaceType=" + KdConstants.createOrder + "&customerCode=" + id + "&requestData=" + dataJson + "&dataSign=" + design; //发请求 String resCreate = HttpUtil.post(url, createParam); Map mapCreate = JSON.parseObject(resCreate, Map.class); //resultCode == 100表示下单成功,预下单成功后立马调用下单接口 if (ObjectUtil.isNotNull(mapCreate.get("resultCode")) && 100 == Integer.valueOf(mapCreate.get("resultCode").toString())) { Map mapData = JSON.parseObject(mapCreate.get("data").toString(), Map.class); log.info("快递鸟下单成功 单号:--------------------------------" + mapData.get("kdnOrderCode").toString()); return mapData.get("kdnOrderCode").toString(); } } else { throw new ServiceException(map.get("reason").toString()); } return null; } private void fillParam(PreOrderModelDTO preOrderModel) { if (preOrderModel.getAppointmentType() == 1 ){ if (LocalDateTime.now().plusHours(2).isAfter(preOrderModel.getAppointmentTime())){ throw new ServiceException("预约单必须在当前时间完后2小时"); } } //填充送货人的经纬度 LongitudeLatitude longitudeLatitudeSender = GaoDeUtil.getLongitudeLatitude(preOrderModel.getSender().getProvinceName()+preOrderModel.getSender().getCityName()+preOrderModel.getSender().getAreaName()+preOrderModel.getSender().getAddress()); preOrderModel.getSender().setLongitude(longitudeLatitudeSender.getLongitude()); preOrderModel.getSender().setLatitude(longitudeLatitudeSender.getLatitude()); //填充收货人的经纬度 LongitudeLatitude longitudeLatitudeReceiver = GaoDeUtil.getLongitudeLatitude(preOrderModel.getReceiver().getProvinceName()+preOrderModel.getReceiver().getCityName()+preOrderModel.getReceiver().getAreaName()+preOrderModel.getReceiver().getAddress()); preOrderModel.getReceiver().setLongitude(longitudeLatitudeReceiver.getLongitude()); preOrderModel.getReceiver().setLatitude(longitudeLatitudeReceiver.getLatitude()); //获取下单人信息 preOrderModel.setOrderName(AdminUserContext.getAdminUserName()); preOrderModel.setOrderPhone("13127911751"); } private void fillParam(CreateStoreModel model) { LongitudeLatitude longitudeLatitudeSender = GaoDeUtil.getLongitudeLatitude(model.getProvinceName() + model.getCityName() + model.getAreaName() + model.getAddress()); model.setLongitude(longitudeLatitudeSender.getLongitude()); model.setLatitude(longitudeLatitudeSender.getLatitude()); //填充送货人的经纬度 } /** * 推送待接单状态 接口指令103,状态码100 * 推送业务员接单状态 接口指令103,状态码201 * 推送业务员到达状态 接口指令103,状态码202 * 推送配送中状态 接口指令103,状态码300 * 推送签收状态 * (签收分为两种签收) 接口指令103,状态码401(正常签收) * 接口指令103,状态码402(退回签收) * 推送取消状态 接口指令103,状态码500 * 推送下单失败状态 接口指令103,状态码600 * 推送订单费用状态 接口指令103,状态码206 */ @Override public resReturnBackBase kdnReturnBack(ReturnBackInstant returnBackBase) { Map map = JSON.parseObject(returnBackBase.getRequestData(), Map.class); resReturnBackBase base = new resReturnBackBase(); base.setKdnOrderCode(map.get("kdnOrderCode").toString()); //验签 OrderSendDO aDo = orderSendManager.getOne(new LambdaQueryWrapper().eq(OrderSendDO::getKdnOrderCode,map.get("kdnOrderCode").toString())); if (ObjectUtil.isNull(aDo)){ // base.setRequestData("验签失败"); base.setResultCode(1002); base.setReason("未找到对应的商家订单"); return base; } OrderDO orderDO = orderManager.getById(aDo.getOrderId()); // if (!checkDesign(aDo, returnBackBase.getDataSign())) { // base.setRequestData("验签失败"); // base.setResultCode(1002); // return base; // } if (ObjectUtil.isNull(aDo) || ObjectUtil.isNull(orderDO)) { base.setReason("未找到对应的订单"); log.error("未找到对应的订单-------------------------------" + map.get("orderCode").toString()); base.setResultCode(1002); return base; } switch (map.get("orderStatus").toString()) { case KdConstants.callBackPreAccept: aDo.setCreateOrderSuccess(map); break; case KdConstants.callBackAccept: aDo.setUserTakeOrder(map); break; case KdConstants.callBackAttain: aDo.setUserArrives(map); break; case KdConstants.callBackSending: aDo.setUserSending(map); break; case KdConstants.callBackSign: aDo.setSignIn(map); aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SINGE); if (OrderTypeEnum.TO_B.equals(orderDO.getType())) { orderDO.setStatus(SaleOrderStatusEnum.ORDER_END); } if (OrderTypeEnum.TO_C.equals(orderDO.getType())) { orderDO.setStatus(SaleOrderStatusEnum.TO_BE_RETURN); } break; case KdConstants.callBackSignRefuse: aDo.setSignIn(map); aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SINGE_NOT); if (OrderTypeEnum.TO_B.equals(orderDO.getType())) { orderDO.setStatus(SaleOrderStatusEnum.ORDER_END); } if (OrderTypeEnum.TO_C.equals(orderDO.getType())) { orderDO.setStatus(SaleOrderStatusEnum.TO_BE_RETURN); } break; case KdConstants.callBackCancelStatus: //如果推送取消状态,需要重新下单 aDo.setKdnOrderCode(""); aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SEND); aDo.setSendNo(aDo.getSendNo()+1); break; case KdConstants.callBackCreateOrderFail: //如果下单失败更爱订单状态,清空快递鸟单号,让用户可以重新下单 aDo.setKdnOrderCode(""); aDo.setStatus(SaleOrderSendStatusEnum.TO_BE_SEND); aDo.setSendNo(aDo.getSendNo()+1); break; case KdConstants.callBackFeeStatus: aDo.setOrderFee(map); break; default: base.setResultCode(1002); base.setReason("内部业务异常,麻烦尽快通知商家,tel:13127911751"); } orderSendManager.updateById(aDo); return base; } // private Boolean checkDesign(OrderSendDO aDo, String dataSign) { // try { // PreOrderModel model = new PreOrderModel(); // converter.copyProperties(model, aDo); // model.setGoodsList(aDo.getGoodsList()); // String design = URLEncoder.encode(Base64.encode(DigestUtil.md5Hex(JSONUtil.toJsonStr(model) + apiKey)), "UTF-8"); // if (dataSign.equals(design)) { // return true; // } // return false; // } catch (Exception e) { // return false; // } // } }