feat: 订单
parent
56f22d1e5d
commit
7a1d5d0a34
|
|
@ -29,8 +29,8 @@ import java.util.Map;
|
|||
*/
|
||||
@Api(tags = "支付宝回调接口")
|
||||
@RestController
|
||||
@RequestMapping("/rest/v1/alipay")
|
||||
public class AlipayController extends XktBaseController {
|
||||
@RequestMapping("/rest/v1/alipay-callback")
|
||||
public class AlipayCallbackController extends XktBaseController {
|
||||
|
||||
private static final String SUCCESS = "success";
|
||||
private static final String FAILURE = "failure";
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package com.ruoyi.web.controller.xkt;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ruoyi.common.core.controller.XktBaseController;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.web.controller.xkt.vo.express.ZtoPrintOrderReqVO;
|
||||
import com.ruoyi.web.controller.xkt.vo.express.ZtoPrintOrderRespVO;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-17 14:18
|
||||
*/
|
||||
@Api(tags = "物流回调接口")
|
||||
@RestController
|
||||
@RequestMapping("/rest/v1/express-callback")
|
||||
public class ExpressCallbackController extends XktBaseController {
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
/**
|
||||
* 中通-生成面单图片/PDF回推
|
||||
* <p>
|
||||
* 采用http协议,字符集编码为UTF-8,ContentType:"application/json",请求方式:POST
|
||||
* 开放平台会根据三方返回的status字段判断此次推送是否成功
|
||||
* 若三方返回false,或触达出现异常,开放平台侧会进行推送重试,重试最大次数为16次
|
||||
*
|
||||
* @param vo
|
||||
* @return
|
||||
*/
|
||||
@ApiOperation("中通-生成面单图片/PDF回推")
|
||||
@PostMapping("zto/print-order")
|
||||
public ZtoPrintOrderRespVO ztoPrintOrder(@RequestBody ZtoPrintOrderReqVO vo) {
|
||||
if (StrUtil.isNotEmpty(vo.getBillCode())
|
||||
&& StrUtil.isNotEmpty(vo.getResult())) {
|
||||
//缓存30分钟
|
||||
redisCache.setCacheObject("ZTO-"+vo.getBillCode(),vo.getResult(),30, TimeUnit.MINUTES);
|
||||
return ZtoPrintOrderRespVO.success();
|
||||
}
|
||||
return ZtoPrintOrderRespVO.failure();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruoyi.web.controller.xkt.vo.express;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-17 16:40
|
||||
*/
|
||||
@Data
|
||||
public class ZtoPrintOrderReqVO {
|
||||
/**
|
||||
* 运单号
|
||||
*/
|
||||
private String billCode;
|
||||
/**
|
||||
* 打印类型(0:JPG, 1:PDF.默认为PDF)
|
||||
*/
|
||||
private String printType;
|
||||
/**
|
||||
* 图片或PDF的Base64编码
|
||||
*/
|
||||
private String result;
|
||||
/**
|
||||
* 消息签名dataDigest=base64(md5(result+billCode))
|
||||
*/
|
||||
private String dataDigest;
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package com.ruoyi.web.controller.xkt.vo.express;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-17 16:34
|
||||
*/
|
||||
@Data
|
||||
public class ZtoPrintOrderRespVO {
|
||||
/**
|
||||
* 默认false,中通根据status=true来判断是否推送成功
|
||||
*/
|
||||
private Boolean status;
|
||||
/**
|
||||
* 响应说明
|
||||
*/
|
||||
private String message;
|
||||
/**
|
||||
* 响应结果
|
||||
*/
|
||||
private String result;
|
||||
/**
|
||||
* 响应状态码
|
||||
*/
|
||||
private String statusCode;
|
||||
|
||||
public static ZtoPrintOrderRespVO success() {
|
||||
ZtoPrintOrderRespVO vo = new ZtoPrintOrderRespVO();
|
||||
vo.setStatus(true);
|
||||
vo.setMessage("success");
|
||||
vo.setResult("success");
|
||||
vo.setStatusCode("0");
|
||||
return vo;
|
||||
}
|
||||
|
||||
public static ZtoPrintOrderRespVO failure() {
|
||||
ZtoPrintOrderRespVO vo = new ZtoPrintOrderRespVO();
|
||||
vo.setStatus(false);
|
||||
vo.setMessage("failure");
|
||||
vo.setResult("failure");
|
||||
vo.setStatusCode("0");
|
||||
return vo;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -178,6 +178,14 @@ zto:
|
|||
accountId: test
|
||||
accountPassword: ZTO123
|
||||
|
||||
# 圆通配置
|
||||
yto:
|
||||
appKey: K9991024989
|
||||
appSecret: u2Z1F7Fh
|
||||
appKey2: TEST
|
||||
appSecret2: 123456
|
||||
gatewayUrl: https://openuat.yto56test.com:6443/
|
||||
|
||||
# 支付宝配置
|
||||
alipay:
|
||||
appId: 9021000144616672
|
||||
|
|
|
|||
|
|
@ -116,7 +116,9 @@ public class SecurityConfig
|
|||
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
|
||||
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
|
||||
//支付宝回调
|
||||
.antMatchers("/rest/v1/alipay-notify").permitAll()
|
||||
.antMatchers("/rest/v1/alipay-callback/**").permitAll()
|
||||
//物流回调
|
||||
.antMatchers("/rest/v1/express-callback/**").permitAll()
|
||||
// 除上面外的所有请求全部需要鉴权认证
|
||||
.anyRequest().authenticated();
|
||||
})
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ import lombok.Getter;
|
|||
@AllArgsConstructor
|
||||
public enum EExpressChannel {
|
||||
|
||||
ZTO(1, "中通", 1L, "ZTO");
|
||||
ZTO(1, "中通", 1L, "ZTO"),
|
||||
YTO(2, "圆通", 2L, "YTO"),
|
||||
;
|
||||
|
||||
private final Integer value;
|
||||
private final String label;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,132 @@
|
|||
package com.ruoyi.xkt.manager.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.xkt.dto.express.ExpressShipReqDTO;
|
||||
import com.ruoyi.xkt.enums.EExpressChannel;
|
||||
import com.ruoyi.xkt.manager.ExpressManager;
|
||||
import com.ruoyi.xkt.thirdpart.yto.YtoCreateOrderParam;
|
||||
import com.ruoyi.xkt.thirdpart.yto.YtoPrintOrderParam;
|
||||
import com.ruoyi.xkt.thirdpart.yto.YtoPublicRequest;
|
||||
import com.ruoyi.xkt.thirdpart.yto.YtoSignUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-17 16:55
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class YtoExpressManagerImpl implements ExpressManager {
|
||||
|
||||
@Value("${yto.appKey:}")
|
||||
private String appKey;
|
||||
|
||||
@Value("${yto.appSecret:}")
|
||||
private String appSecret;
|
||||
|
||||
@Value("${yto.appKey2:}")
|
||||
private String appKey2;
|
||||
|
||||
@Value("${yto.appSecret2:}")
|
||||
private String appSecret2;
|
||||
|
||||
@Value("${yto.gatewayUrl:}")
|
||||
private String gatewayUrl;
|
||||
|
||||
@Override
|
||||
public EExpressChannel channel() {
|
||||
return EExpressChannel.YTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shipStoreOrder(ExpressShipReqDTO shipReqDTO) {
|
||||
YtoCreateOrderParam createOrderParam = trans2CreateOrderReq(shipReqDTO);
|
||||
try {
|
||||
String param = JSONUtil.toJsonStr(createOrderParam);
|
||||
String sign = YtoSignUtil.sign("privacy_create_adapter", "v1", param, appSecret);
|
||||
YtoPublicRequest request = YtoPublicRequest.builder()
|
||||
.timestamp(System.currentTimeMillis())
|
||||
.param(param)
|
||||
.format(YtoPublicRequest.EFormat.JSON)
|
||||
.sign(sign).build();
|
||||
String rtnStr = HttpUtil.post(gatewayUrl + "open/privacy_create_adapter/v1/N364gM/" + appKey,
|
||||
JSONUtil.toJsonStr(request));
|
||||
log.info("圆通订单创建返回信息: {}", rtnStr);
|
||||
JSONObject rtnJson = JSONUtil.parseObj(rtnStr);
|
||||
String waybillNo = rtnJson.getStr("mailNo");
|
||||
if (StrUtil.isNotEmpty(waybillNo)) {
|
||||
return waybillNo;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("圆通订单创建异常", e);
|
||||
}
|
||||
throw new ServiceException("圆通订单创建失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String printOrder(String waybillNo) {
|
||||
YtoPrintOrderParam printOrderParam = YtoPrintOrderParam.builder().waybillNo(waybillNo).build();
|
||||
try {
|
||||
String param = JSONUtil.toJsonStr(printOrderParam);
|
||||
String sign = YtoSignUtil.sign("waybill_print_adapter", "v1", param, appSecret);
|
||||
YtoPublicRequest request = YtoPublicRequest.builder()
|
||||
.timestamp(System.currentTimeMillis())
|
||||
.param(param)
|
||||
.format(YtoPublicRequest.EFormat.JSON)
|
||||
.sign(sign).build();
|
||||
String rtnStr = HttpUtil.post(gatewayUrl + "open/waybill_print_adapter/v1/N364gM/" + appKey,
|
||||
JSONUtil.toJsonStr(request));
|
||||
log.info("圆通打印回单返回信息: {}", rtnStr);
|
||||
JSONObject rtnJson = JSONUtil.parseObj(rtnStr);
|
||||
String rtn = rtnJson.getJSONObject("data").getStr("pdfBase64");
|
||||
if (StrUtil.isNotEmpty(rtn)) {
|
||||
return rtn;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("圆通打印回单异常", e);
|
||||
}
|
||||
throw new ServiceException("圆通打印回单失败");
|
||||
}
|
||||
|
||||
|
||||
private YtoCreateOrderParam trans2CreateOrderReq(ExpressShipReqDTO shipReqDTO) {
|
||||
YtoCreateOrderParam reqDTO = new YtoCreateOrderParam();
|
||||
reqDTO.setLogisticsNo(shipReqDTO.getExpressReqNo());
|
||||
|
||||
reqDTO.setSenderName(shipReqDTO.getOriginContactName());
|
||||
reqDTO.setSenderProvinceName(shipReqDTO.getOriginProvinceName());
|
||||
reqDTO.setSenderCityName(shipReqDTO.getOriginCityName());
|
||||
reqDTO.setSenderCountyName(shipReqDTO.getOriginCountyName());
|
||||
reqDTO.setSenderAddress(shipReqDTO.getOriginDetailAddress());
|
||||
reqDTO.setSenderMobile(shipReqDTO.getOriginContactPhoneNumber());
|
||||
|
||||
reqDTO.setRecipientName(shipReqDTO.getDestinationContactName());
|
||||
reqDTO.setRecipientProvinceName(shipReqDTO.getDestinationProvinceName());
|
||||
reqDTO.setRecipientCityName(shipReqDTO.getDestinationCityName());
|
||||
reqDTO.setRecipientCountyName(shipReqDTO.getDestinationCountyName());
|
||||
reqDTO.setRecipientAddress(shipReqDTO.getDestinationDetailAddress());
|
||||
reqDTO.setRecipientMobile(shipReqDTO.getDestinationContactPhoneNumber());
|
||||
|
||||
int goodsSize = shipReqDTO.getOrderItems().size();
|
||||
if (shipReqDTO.getOrderItems().size() > 20) {
|
||||
throw new ServiceException("圆通每次发货物品在20个以内!");
|
||||
}
|
||||
reqDTO.setGoods(new ArrayList<>(goodsSize));
|
||||
for (ExpressShipReqDTO.OrderItem item : shipReqDTO.getOrderItems()) {
|
||||
YtoCreateOrderParam.OrderGoods goods = new YtoCreateOrderParam.OrderGoods();
|
||||
reqDTO.getGoods().add(goods);
|
||||
goods.setName(item.getName());
|
||||
goods.setQuantity(item.getQuantity());
|
||||
}
|
||||
return reqDTO;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,24 +2,30 @@ package com.ruoyi.xkt.manager.impl;
|
|||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.ruoyi.common.core.redis.RedisCache;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.xkt.dto.express.ExpressShipReqDTO;
|
||||
import com.ruoyi.xkt.enums.EExpressChannel;
|
||||
import com.ruoyi.xkt.manager.ExpressManager;
|
||||
import com.ruoyi.xkt.thirdpart.zto.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-15 15:45
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ZtoExpressManagerImpl implements ExpressManager {
|
||||
public class ZtoExpressManagerImpl implements ExpressManager, InitializingBean {
|
||||
|
||||
private static final String CREATE_ORDER_URI = "zto.open.createOrder";
|
||||
|
||||
|
|
@ -42,19 +48,23 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
@Value("${zto.accountPassword:}")
|
||||
private String accountPassword;
|
||||
|
||||
@Autowired
|
||||
private RedisCache redisCache;
|
||||
|
||||
private ZopClient client;
|
||||
|
||||
@Override
|
||||
public EExpressChannel channel() {
|
||||
return EExpressChannel.ZTO;
|
||||
return EExpressChannel.YTO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String shipStoreOrder(ExpressShipReqDTO shipReqDTO) {
|
||||
Assert.notNull(shipReqDTO);
|
||||
Assert.notEmpty(shipReqDTO.getExpressReqNo());
|
||||
ZtoCreateOrderReqDTO createOrderReq = trans2CreateOrderReq(shipReqDTO);
|
||||
ZopClient client = new ZopClient(appKey, appSecret);
|
||||
ZtoCreateOrderParam createOrderParam = trans2CreateOrderReq(shipReqDTO);
|
||||
ZopPublicRequest request = new ZopPublicRequest();
|
||||
request.setBody(JSONUtil.toJsonStr(createOrderReq));
|
||||
request.setBody(JSONUtil.toJsonStr(createOrderParam));
|
||||
request.setUrl(gatewayUrl + CREATE_ORDER_URI);
|
||||
request.setEncryptionType(EncryptionType.MD5);
|
||||
try {
|
||||
|
|
@ -75,9 +85,8 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
@Override
|
||||
public String printOrder(String waybillNo) {
|
||||
Assert.notEmpty(waybillNo);
|
||||
ZopClient client = new ZopClient(appKey, appSecret);
|
||||
ZopPublicRequest request = new ZopPublicRequest();
|
||||
request.setBody(JSONUtil.toJsonStr(new ZtoPrintOrderReqDTO(1,waybillNo,true)));
|
||||
request.setBody(JSONUtil.toJsonStr(new ZtoPrintOrderParam(1, waybillNo, true)));
|
||||
request.setUrl(gatewayUrl + ORDER_PRINT_URI);
|
||||
request.setEncryptionType(EncryptionType.MD5);
|
||||
try {
|
||||
|
|
@ -87,7 +96,12 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
boolean success = bodyJson.getBool("status");
|
||||
if (success) {
|
||||
//TODO 测试环境接口不通
|
||||
return bodyJson.getJSONObject("result").getStr("billCode");
|
||||
//等待推送
|
||||
TimeUnit.SECONDS.sleep(3);
|
||||
String rtn = redisCache.getCacheObject("ZTO_" + waybillNo);
|
||||
if (StrUtil.isNotEmpty(rtn)) {
|
||||
return rtn;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("中通订单打印异常", e);
|
||||
|
|
@ -102,7 +116,6 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
* @return
|
||||
*/
|
||||
public JSONObject structureNamePhoneAddress(String str) {
|
||||
ZopClient client = new ZopClient(appKey, appSecret);
|
||||
ZopPublicRequest request = new ZopPublicRequest();
|
||||
JSONObject body = new JSONObject();
|
||||
body.set("address", str);
|
||||
|
|
@ -123,8 +136,8 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
throw new ServiceException("中通智能解析失败");
|
||||
}
|
||||
|
||||
private ZtoCreateOrderReqDTO trans2CreateOrderReq(ExpressShipReqDTO expressShipReqDTO) {
|
||||
ZtoCreateOrderReqDTO reqDTO = new ZtoCreateOrderReqDTO();
|
||||
private ZtoCreateOrderParam trans2CreateOrderReq(ExpressShipReqDTO expressShipReqDTO) {
|
||||
ZtoCreateOrderParam reqDTO = new ZtoCreateOrderParam();
|
||||
//合作模式 ,1:集团客户;2:非集团客户
|
||||
reqDTO.setPartnerType("2");
|
||||
//partnerType为1时,orderType:1:全网件 2:预约件。 partnerType为2时,orderType:1:全网件 2:预约件(返回运单号) 3:预约件(不返回运单号) 4:星联全网件
|
||||
|
|
@ -133,7 +146,7 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
reqDTO.setPartnerOrderCode(expressShipReqDTO.getExpressReqNo());
|
||||
|
||||
//账号信息
|
||||
ZtoCreateOrderReqDTO.AccountInfo accountInfo = new ZtoCreateOrderReqDTO.AccountInfo();
|
||||
ZtoCreateOrderParam.AccountInfo accountInfo = new ZtoCreateOrderParam.AccountInfo();
|
||||
reqDTO.setAccountInfo(accountInfo);
|
||||
//电子面单账号(partnerType为2,orderType传1,2,4时必传)
|
||||
accountInfo.setAccountId(accountId);
|
||||
|
|
@ -145,7 +158,7 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
accountInfo.setCustomerId(null);
|
||||
|
||||
//发件人信息
|
||||
ZtoCreateOrderReqDTO.SenderInfo senderInfo = new ZtoCreateOrderReqDTO.SenderInfo();
|
||||
ZtoCreateOrderParam.SenderInfo senderInfo = new ZtoCreateOrderParam.SenderInfo();
|
||||
reqDTO.setSenderInfo(senderInfo);
|
||||
senderInfo.setSenderName(expressShipReqDTO.getOriginCountyName());
|
||||
senderInfo.setSenderPhone(expressShipReqDTO.getOriginContactPhoneNumber());
|
||||
|
|
@ -155,7 +168,7 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
senderInfo.setSenderAddress(expressShipReqDTO.getOriginDetailAddress());
|
||||
|
||||
//收件人信息
|
||||
ZtoCreateOrderReqDTO.ReceiveInfo receiveInfo = new ZtoCreateOrderReqDTO.ReceiveInfo();
|
||||
ZtoCreateOrderParam.ReceiveInfo receiveInfo = new ZtoCreateOrderParam.ReceiveInfo();
|
||||
reqDTO.setReceiveInfo(receiveInfo);
|
||||
receiveInfo.setReceiverName(expressShipReqDTO.getDestinationContactName());
|
||||
receiveInfo.setReceiverPhone(expressShipReqDTO.getDestinationContactPhoneNumber());
|
||||
|
|
@ -166,10 +179,14 @@ public class ZtoExpressManagerImpl implements ExpressManager {
|
|||
|
||||
//货物信息
|
||||
reqDTO.setOrderItems(BeanUtil.copyToList(expressShipReqDTO.getOrderItems(),
|
||||
ZtoCreateOrderReqDTO.OrderItem.class));
|
||||
ZtoCreateOrderParam.OrderItem.class));
|
||||
|
||||
return reqDTO;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.client = new ZopClient(appKey, appSecret);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,179 @@
|
|||
package com.ruoyi.xkt.thirdpart.yto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-15 19:20
|
||||
*/
|
||||
@Data
|
||||
public class YtoCreateOrderParam {
|
||||
/**
|
||||
* 物流单号,打印拉取运单号前,物流单号和渠道唯一确定一笔快递物流订单。注:最低长度为7
|
||||
*/
|
||||
private String logisticsNo;
|
||||
/**
|
||||
* 寄件人姓名
|
||||
*/
|
||||
private String senderName;
|
||||
/**
|
||||
* 寄件人省名称
|
||||
*/
|
||||
private String senderProvinceName;
|
||||
/**
|
||||
* 寄件人市名称
|
||||
*/
|
||||
private String senderCityName;
|
||||
/**
|
||||
* 寄件人区县名称
|
||||
*/
|
||||
private String senderCountyName;
|
||||
/**
|
||||
* 寄件人乡镇名称
|
||||
*/
|
||||
private String senderTownName;
|
||||
/**
|
||||
* 寄件人详细地址
|
||||
*/
|
||||
private String senderAddress;
|
||||
/**
|
||||
* 寄件人联系电话
|
||||
*/
|
||||
private String senderMobile;
|
||||
/**
|
||||
* 收件人姓名
|
||||
*/
|
||||
private String recipientName;
|
||||
/**
|
||||
* 收件人省名称
|
||||
*/
|
||||
private String recipientProvinceName;
|
||||
/**
|
||||
* 收件人市名称
|
||||
*/
|
||||
private String recipientCityName;
|
||||
/**
|
||||
* 收件人区县名称
|
||||
*/
|
||||
private String recipientCountyName;
|
||||
/**
|
||||
* 收件人乡镇名称
|
||||
*/
|
||||
private String recipientTownName;
|
||||
/**
|
||||
* 收件人详细地址
|
||||
*/
|
||||
private String recipientAddress;
|
||||
/**
|
||||
* 收件人联系电话
|
||||
*/
|
||||
private String recipientMobile;
|
||||
/**
|
||||
* 备注,打印在面单上的备注内容
|
||||
*/
|
||||
private String remark;
|
||||
/**
|
||||
* 寄件码或取件码
|
||||
*/
|
||||
private String gotCode;
|
||||
/**
|
||||
* 增值服务列表
|
||||
*/
|
||||
private List<OrderIncrement> increments;
|
||||
/**
|
||||
* 物品列表,注:支持20个以内
|
||||
*/
|
||||
private List<OrderGoods> goods;
|
||||
/**
|
||||
* 预约上门取件开始时间,”yyyy-MM-dd HH:mm:ss”格式化,注:预约取件时间规则为下单当天的00:00:00至下单当天+6天的23:59:59。
|
||||
*/
|
||||
private String startTime;
|
||||
/**
|
||||
* 预约上门取件结束时间,”yyyy-MM-dd HH:mm:ss”格式化,注:预约取件时间规则为下单当天的00:00:00至下单当天+6天的23:59:59。
|
||||
*/
|
||||
private String endTime;
|
||||
/**
|
||||
* 客户业务类型,可以对客户订单进行业务或渠道区分。
|
||||
*/
|
||||
private String cstBusinessType;
|
||||
/**
|
||||
* 客户的订单号
|
||||
*/
|
||||
private String cstOrderNo;
|
||||
/**
|
||||
* 实名信息
|
||||
*/
|
||||
private String realNameInfo;
|
||||
/**
|
||||
* 下单总重量,单位:千克,小数后三位
|
||||
*/
|
||||
private String weight;
|
||||
/**
|
||||
* 产品编号:YZD-圆准达;XTCTK-同城特快;HKJ-航空件;PK-普快,默认PK
|
||||
*/
|
||||
private String productCode;
|
||||
|
||||
@Data
|
||||
public static class OrderIncrement {
|
||||
/**
|
||||
* 增值类型:1-代收货款;2-到付;4-保价,注:增值服务不能同时选择代收和到付。
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
* 金额,单位:元,代收货款金额:[3,20000];到付金额:[1,5000];保价金额:[100,30000]。
|
||||
*/
|
||||
private String amount;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class OrderGoods {
|
||||
/**
|
||||
* 物品名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 重量,单位:千克
|
||||
*/
|
||||
private String weight;
|
||||
/**
|
||||
* 长,单位:米
|
||||
*/
|
||||
private String length;
|
||||
/**
|
||||
* 宽,单位:米
|
||||
*/
|
||||
private String width;
|
||||
/**
|
||||
* 高,单位:米
|
||||
*/
|
||||
private String height;
|
||||
/**
|
||||
* 单价,单位:元
|
||||
*/
|
||||
private String price;
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
private Integer quantity;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class RealNameInfo {
|
||||
/**
|
||||
* 姓名
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 证件号
|
||||
*/
|
||||
private String cerNum;
|
||||
/**
|
||||
* 证件类型: 11:居民身份证;12:临时居民身份证;13:户口簿;14:中国人民解放军军人身份证件;15:中国人民武装警察身份证件;16:港澳居民来往内地通行证;17:台湾居民通往大陆通行证;18:外国公民护照;19:中国公民护照;20:港澳台居民居住证;101:机构代码;102:税务登记号:103:统一社会信用代码
|
||||
*/
|
||||
private String cerType;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.ruoyi.xkt.thirdpart.yto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-04-15 19:20
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class YtoPrintOrderParam {
|
||||
/**
|
||||
* 圆通运单号
|
||||
*/
|
||||
private String waybillNo;
|
||||
/**
|
||||
* 备注,最多130个字符
|
||||
*/
|
||||
private String remark;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.ruoyi.xkt.thirdpart.yto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class YtoPublicRequest {
|
||||
/**
|
||||
* 签名
|
||||
*/
|
||||
private String sign;
|
||||
/**
|
||||
* 时间戳
|
||||
*/
|
||||
private Long timestamp;
|
||||
/**
|
||||
* 传递的参数
|
||||
*/
|
||||
private String param;
|
||||
/**
|
||||
* param格式
|
||||
*/
|
||||
private EFormat format;
|
||||
|
||||
public enum EFormat {
|
||||
JSON,
|
||||
XML
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.ruoyi.xkt.thirdpart.yto;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
|
||||
/**
|
||||
* @author liangyq
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
public class YtoSignUtil {
|
||||
/**
|
||||
* 序号 步骤
|
||||
* 1 在POST时用“sign”字段进行签名验证。
|
||||
* 2 将 param+method(方法)+v(版本) 拼接得到 data,将 data和 客户密钥 拼接。(通过 控制台——接口管理,添加自己所需接口,即可得到相应的测试地址、客户编码、客户密钥、方法和版本)
|
||||
* 3 假设data内容为: opentest, partnerId(客户密钥)为123456。 则要签名的内容为opentest123456,然后对opentest123456先进行MD5加密,然后转换为base64字符串。 即经过md5(16位byte)和base64后的内容就为 YLstCNa3x8ijQx16e/jqOA==
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static String sign(String method, String version, String param, String secret) {
|
||||
String data = param + method + version;
|
||||
return sign(data, secret);
|
||||
}
|
||||
|
||||
|
||||
public static String sign(String data, String secret) {
|
||||
//进行md5加密,然后对数组进行base64编码
|
||||
byte[] bytes = DigestUtil.md5(data + secret);
|
||||
return Base64.encodeStr(bytes, false, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||
* @date 2025-04-15 19:20
|
||||
*/
|
||||
@Data
|
||||
public class ZtoCreateOrderReqDTO {
|
||||
public class ZtoCreateOrderParam {
|
||||
/**
|
||||
* 合作模式 ,1:集团客户;2:非集团客户
|
||||
*/
|
||||
|
|
@ -11,7 +11,7 @@ import lombok.NoArgsConstructor;
|
|||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ZtoPrintOrderReqDTO {
|
||||
public class ZtoPrintOrderParam {
|
||||
/**
|
||||
* 打印类型(0:JPG, 1:PDF.默认为PDF)
|
||||
*/
|
||||
Loading…
Reference in New Issue