Browse Source

【佳毅兴】【顺丰对接】

wuyx 6 months ago
parent
commit
91105d822a

+ 5 - 5
pom.xml

@@ -85,11 +85,6 @@
 			<artifactId>axis</artifactId>
 			<version>1.4</version>
 		</dependency>
-		<dependency>
-			<groupId>kingdee-sdk</groupId>
-			<artifactId>k3cloud-webapi-client</artifactId>
-			<version>1.8</version>
-		</dependency>
 		<dependency>
 		    <groupId>io.jsonwebtoken</groupId>
 		    <artifactId>jjwt</artifactId>
@@ -186,6 +181,11 @@
 			<version>RELEASE</version>
 			<scope>compile</scope>
 		</dependency>
+		<dependency>
+			<groupId>sf-sdk</groupId>
+			<artifactId>sf-csim-express</artifactId>
+			<version>2.1.7</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 14 - 5
src/main/java/com/uas/eis/controller/ERPController.java

@@ -13,7 +13,7 @@ import java.util.Map;
 /**
  * @author WUYX
  * @email wuyx@usoftchina.com
- * @date 2024-03-25
+ * @date 2024-09-02
  */
 @RestController
 public class ERPController {
@@ -21,11 +21,20 @@ public class ERPController {
     private ERPService erpService;
 
     /**
-     * 创建条码ID
+     * 创建顺丰订单
      */
-    @RequestMapping(value="/erp/createSticker",method=RequestMethod.POST)
+    @RequestMapping(value="/erp/creatSFOrder",method=RequestMethod.POST)
     @ResponseBody
-    public Map<String, Object> createSticker(String master, Integer id){
-        return erpService.createSticker2(master,id);
+    public Map<String, Object> creatSFOrder(String master, Integer id,String emCode){
+        return erpService.creatSFOrder(master,id,emCode);
+    }
+
+    /**
+     * 取消顺丰订单
+     */
+    @RequestMapping(value="/erp/cancelSFOrder",method=RequestMethod.POST)
+    @ResponseBody
+    public Map<String, Object> cancelSFOrder(String master, Integer id,String emCode){
+        return erpService.cancelSFOrder(master,id,emCode);
     }
 }

+ 11 - 0
src/main/java/com/uas/eis/entity/sf/SFApiResp.java

@@ -0,0 +1,11 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFApiResp{
+    String apiErrorMsg;
+    String apiResponseID;
+    String apiResultCode;
+    String apiResultData;
+}

+ 10 - 0
src/main/java/com/uas/eis/entity/sf/SFApiRespData.java

@@ -0,0 +1,10 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFApiRespData{
+    boolean success;
+    String errorCode;
+    String errorMsg;
+}

+ 18 - 0
src/main/java/com/uas/eis/entity/sf/SFCancelOrder.java

@@ -0,0 +1,18 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SFCancelOrder {
+    //#	属性名	类型(约束)	必填	默认值	描述
+    //1	orderId	String(64)	是		客户订单号
+    String orderId;
+    //2	waybillNoInfoList	List	否		顺丰运单号
+    List<SFWaybillNoInfo> waybillNoInfoList;
+    //3	resStatus	Number(1)	是		备注 1:客户订单号与顺丰运单不匹配 2 :操作成功
+    Integer resStatus;
+    //4	extraInfoList	List	否		扩展属性
+    List<SFExtraInfo> extraInfoList;
+}

+ 8 - 0
src/main/java/com/uas/eis/entity/sf/SFCancelOrderResp.java

@@ -0,0 +1,8 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFCancelOrderResp  extends SFApiRespData {
+    SFCancelOrder msgData;
+}

+ 40 - 0
src/main/java/com/uas/eis/entity/sf/SFCargoDetail.java

@@ -0,0 +1,40 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+/*
+* 托寄物信息
+* */
+public class SFCargoDetail {
+    //#	属性名	类型(约束)	必填	描述
+    //1	name	String(128)	是	货物名称,如果需要生成电子 运单,则为必填
+    String name;
+    //2	count	Number(5)	条件	货物数量 跨境件报关需要填写
+    Double count;
+    //3	unit	String(30)	条件	货物单位,如:个、台、本, 跨境件报关需要填写
+    String unit;
+    //4	weight	Number(16,3)	条件	订单货物单位重量,包含子母件, 单位千克,精确到小数点后3位 跨境件报关需要填写
+    //5	amount	Number(17,3)	条件	货物单价,精确到小数点后3位, 跨境件报关需要填写
+    //6	currency	String(5)	条件	货物单价的币别: 参照附录《国际件币别表》
+    //7	sourceArea	String(5)	条件	原产地国别, 跨境件报关需要填写
+    //8	productRecordNo	String(18)	否	货物产品国检备案编号
+    //9	goodPrepardNo	String(100)	否	商品海关备案号
+    //10	taxNo	String(100)	否	商品行邮税号
+    //11	hsCode	String(100)	否	海关编码
+    //12	goodsCode	String(60)	否	商品编号
+    //13	brand	String(60)	否	货物品牌
+    //14	specifications	String(60)	否	货物规格型号
+    //15	manufacturer	String(100)	否	生产厂家
+    //16	shipmentWeight	Double (16,3)	否	托寄物毛重
+    //17	length	Double (16,3)	否	托寄物长
+    //18	width	Double (16,3)	否	托寄物宽
+    //19	height	Double (16,3)	否	托寄物高
+    //20	volume	Double (16,2)	否	托寄物体积
+    //21	cargoDeclaredValue	Double (16,5)	否	托寄物声明价值(杭州口岸必填)
+    //22	declaredValueDeclaredCurrency	String(5)	否	托寄物声明价值币别(杭州口岸必填)
+    //23	cargoId	String(60)	否	货物id(逆向物流)
+    //24	intelligentInspection	Number(1)	否	智能验货标识(1-是,0-否) (逆向物流)
+    //25	snCode	String(4000)	否	货物标识码(逆向物流)
+    //26	stateBarCode	String(50)	否	国条码
+}

+ 33 - 0
src/main/java/com/uas/eis/entity/sf/SFContactInfo.java

@@ -0,0 +1,33 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+/*
+* 收寄双方信息
+* */
+public class SFContactInfo {
+    //1	contactType	Number(1)	是	地址类型: 1,寄件方信息 2,到件方信息
+    int contactType;
+    //2	company	String(100)	条件	公司名称
+    String company;
+    //3	contact	String(100)	条件	联系人
+    String contact;
+    //4	tel	String(20)	条件	联系电话(tel和mobile字段必填其中一个)
+    String tel;
+    //5	mobile	String(20)	条件	手机(tel和mobile字段必填其中一个)
+    String mobile;
+    //6	country	String(30)	是	国家或地区代码 例如:内地件CN 香港 852
+    String country = "CN";
+    //7	province	String(30)	否	所在省级行政区名称,必须是标准的省级行政区名称如:北 京、广东省、广西壮族自治区等;此字段影响原寄地代码识 别,建议尽可能传该字段的值
+    //8	city	String(100)	否	所在地级行政区名称,必须是标准的城市称谓 如:北京市、 深圳市、大理白族自治州等; 此字段影响原寄地代码识别, 建议尽可能传该字段的值
+    //9	county	String(30)	否	所在县/区级行政区名称,必须 是标准的县/区称谓,如:福田区,南涧彝族自治县、准格尔旗等
+    //10	address	String(200)	是	详细地址,若有四级行政区划,如镇/街道等信息可拼接至此字段,格式样例:镇/街道+详细地址。若province/city 字段的值不传,此字段必须包含省市信息,避免影响原寄地代码识别,如:广东省深圳市福田区新洲十一街万基商务大厦10楼;此字段地址必须详细,否则会影响目的地中转识别;
+    String address;
+    //11	postCode	String(25)	条件	邮编,跨境件必填(中国内地, 港澳台互寄除外)
+    //12	email	String(200)	否	邮箱地址
+    //13	taxNo	String(100)	否	税号
+    //14	contactRemark	String(100)	否	联系人属性(跨境件或国际件需要)
+    //15	certType	String(200)	否	证件类型(跨境件或国际件需要),参考 《证件类型说明》
+    //16	certNo	String(1000)	否	证件号码(跨境件或国际件需要),参考《证件类型说明》
+}

+ 54 - 0
src/main/java/com/uas/eis/entity/sf/SFCreatOrderReq.java

@@ -0,0 +1,54 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+import java.util.List;
+@Data
+public class SFCreatOrderReq {
+    String language = "zh-CN";//String(10) 响应报文的语言, 缺省值为zh-CN,目前支持以下值zh-CN 表示中文简体, zh-TW或zh-HK或 zh-MO表示中文繁体, en表示英文
+    String orderId;//客户订单号,重复使用订单号时返回第一次下单成功时的运单信息
+    //waybillNoInfoList	List	否		顺丰运单号
+    //customsInfo	CustomsInfo	否		报关信息,查看《海关配置流程指引》
+    List<SFCargoDetail> cargoDetails;//托寄物信息
+    String cargoDesc;//String(20)	否		拖寄物类型描述,如: 文件,电子产品,衣服等
+    //extraInfoList	List	否		扩展属性
+    List<SFExtraInfo> extraInfoList;
+    //serviceList	List	否		增值服务信息,支持附录: 《增值服务产品表》
+    //contactInfoList	List	是		收寄双方信息
+    List<SFContactInfo> contactInfoList;
+    //monthlyCard	String(20)	条件		顺丰月结卡号 月结支付时传值,现结不需传值;沙箱联调可使用测试月结卡号 7551234567(非正式,无须绑定,仅支持联调使用)
+    String monthlyCard = "7551234567";
+    //payMethod	Number(2)	否	1	付款方式,支持以下值: 1:寄方付 2:收方付 3:第三方付
+    int payMethod = 1;
+    //12 expressTypeId	Number(5)	是	1	快件产品类别, 支持附录 《快件产品类别表》 的产品编码值,仅可使用与顺丰销售约定的快件产品
+    int expressTypeId = 2;
+    //13	parcelQty	Number(5)	否	1	包裹数,一个包裹对应一个运单号;若包裹数大于1,则返回一个母运单号和N-1个子运单号
+    int parcelQty = 1;
+    //14	totalLength	Number(16,5)	否		客户订单货物总长,单位厘米, 精确到小数点后3位, 包含子母件
+    //15	totalWidth	Number(16,5)	否		客户订单货物总宽,单位厘米, 精确到小数点后3位, 包含子母件
+    //16	totalHeight	Number(16,5)	否		客户订单货物总高,单位厘米, 精确到小数点后3位, 包含子母件
+    //17	totalVolume	Number(16,5)	否		订单货物总体积,单位立方厘米, 精确到小数点后3位,会用于计抛 (是否计抛具体商务沟通中 双方约定)
+    //18	totalWeight	Number(17,5)	条件		订单货物总重量(郑州空港海关必填), 若为子母件必填, 单位千克, 精确到小数点后3位,如果提供此值, 必须>0 (子母件需>6)
+    Double totalWeight;//待定
+    //19	totalNetWeight	Number(17,5)	否		商品总净重
+    //20	sendStartTm	Date	否	接收 到报 文的 时间	要求上门取件开始时间, 格式: YYYY-MM-DD HH24:MM:SS, 示例: 2012-7-30 09:30:00 (预约单传预约截止时间,不赋值默认按当前时间下发,1小时内取件)
+    //21	isDocall	Number(1)	否	0	是否通过手持终端 通知顺丰收派 员上门收件,支持以下值: 1:要求 0:不要求
+    //22	isSignBack	Number(1)	否	0	是否返回签回单 (签单返还)的运单号, 支持以下值: 1:要求 0:不要求
+    //23	custReferenceNo	String(100)	否		客户参考编码:如客户原始订单号
+    //24	temperatureRange	Number(2)	条件		温度范围类型,当 express_type为12 医药温控件 时必填,支持以下值: 1:冷藏 3:冷冻
+    //25	orderSource	String(50)	否		订单平台类型 (对于平台类客户, 如果需要在订单中 区分订单来源, 则可使用此字段) 天猫:tmall, 拼多多:pinduoduo, 京东 : jd 等平台类型编码
+    //27	remark	String(100)	否		备注
+    //28	isOneselfPickup	Number(1)	否	0	快件自取,支持以下值: 1:客户同意快件自取 0:客户不同意快件自取
+    int isOneselfPickup = 0;
+    //29	filterField	String	否		筛单特殊字段用来人工筛单
+    //30	isReturnQRCode	Number(1)	否	0	是否返回用来退货业务的 二维码URL, 支持以下值: 1:返回二维码 0:不返回二维码
+    //31	specialDeliveryTypeCode	String(3)	否		当EXPRESS_TYPE=235 2:极效前置单(当日达) 5:极效前置小时达 当EXPRESS_TYPE=265 4:预售电标
+    //32	specialDeliveryValue	String(100)	否		特殊派件具体表述 证件类型: 证件后8位如: 1:09296231(1 表示身份证, 暂不支持其他证件)
+    //33	merchantPayOrderNo	String(100)	否		商户支付订单号
+    //34	isReturnSignBackRoute label	Number(1)	否	0	是否返回签回单路由标签: 默认0, 1:返回路由标签, 0:不返回
+    //35	isReturnRoutelabel	Number(1)	是	1	是否返回路由标签: 默认1, 1:返回路由标签, 0:不返回;除部分特殊用户外,其余用户都默认返回
+    //36	isUnifiedWaybillNo	Number(1)	否	0	是否使用国家统一面单号 1:是, 0:否(默认)
+    //37	podModelAddress	String(1024)	否		签单返还范本地址
+    //38	inProcessWaybillNo	String(100)	否		头程运单号(郑州空港海关必填)
+    //39	isGenWaybillNo	Number(1)	否	1	是否需求分配运单号1:分配 0:不分配(若带单号下单,请传值0)
+}

+ 8 - 0
src/main/java/com/uas/eis/entity/sf/SFCreatOrderResp.java

@@ -0,0 +1,8 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFCreatOrderResp extends SFApiRespData {
+    SFCreateOrder msgData;
+}

+ 35 - 0
src/main/java/com/uas/eis/entity/sf/SFCreateOrder.java

@@ -0,0 +1,35 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class SFCreateOrder {
+    //1	orderId	String(64)	是	客户订单号
+    String orderId;
+    //2	originCode	String(10)	否	原寄地区域代码,可用于顺丰 电子运单标签打印
+    String originCode;
+    //3	destCode	String(10)	否	目的地区域代码,可用于顺丰 电子运单标签打印
+    String destCode;
+    //4	filterResult	Number(2)	否	筛单结果: 1:人工确认 2:可收派 3:不可以收派
+    Integer filterResult;
+    //5	remark	String(100)	条件	如果filter_result=3时为必填, 不可以收派的原因代码: 1:收方超范围 2:派方超范围 3:其它原因 高峰管控提示信息 【数字】:【高峰管控提示信息】 (如 4:温馨提示 ,1:春运延时)
+    String remark;
+    //6	url	Number(200)	否	二维码URL (用于CX退货操作的URL)
+    String url;
+    //7	paymentLink	String(200)	否	用于第三方支付运费的URL
+    String paymentLink;
+    //8	isUpstairs	String(1)	否	是否送货上楼 1:是
+    String isUpstairs;
+    //9	isSpecialWarehouseService	String(4)	否	true 包含特殊仓库增值服务
+    String isSpecialWarehouseService;
+    //10	serviceList	List	否	下单补充的增值服务信息
+    List<SFServiceResp> serviceList;
+    //11	returnExtraInfoList	List	否	返回信息扩展属性
+    List<SFExtraInfo> returnExtraInfoList;
+    //12	waybillNoInfoList	List	否	顺丰运单号
+    List<SFWaybillNoInfo> waybillNoInfoList;
+    //13	routeLabelInfo	List	是	路由标签,除少量特殊场景用户外,其余均会返回
+    List<SFRouteLabelInfo> routeLabelInfo;
+}

+ 43 - 0
src/main/java/com/uas/eis/entity/sf/SFExtraInfo.java

@@ -0,0 +1,43 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+/*
+*创建订单:
+* 2.3.7.1 扩展字段备注
+attrName	attrVal
+attr001	物品件数(杭州口岸必填)
+attr002	物品净重,郑州空港口岸, 郑州综保税必须字段,最多保留小数点后四位,单位Kg
+attr003	进出口时间(郑州空港口岸必须字段格式:yyyy-MM-dd hh:mm:ss)
+attr005	商品运输费用,无则填0(郑州综保,杭州海关,重庆口岸 要求字段)
+attr006	报关批次(杭州口岸必填,yyyy-dd-mm)
+attr007	商品保险费用,无则填0(郑州综保,杭州海关,重庆口岸 要求字段)
+attr009	杭州海关版本代码:03
+attr010	电商企业十位编码,郑州综保字段
+attr014	签回单标识,对应值为“singBackInfo”
+attr015	签回单标识,结合attr014使用,英文逗号分隔,对应值attrVal:1:签名,2:盖章,3:登记身份证号,4:收取身份证复印件,5、【收取派件存根】(香港专用) 【其他文件】(香港专用)7、【签收日期】8、【电话号码】,英文逗号分隔
+channelCode	渠道编码,仅限ISV商家传值,报文示例"extraInfoList" : [ {“attrName” : “channelCode”,“attrVal” : “B0101020070191”}]
+haDeliveryOrderId	医管局方主键,用作与顺丰沟通用途。与医管局沟通订单状态时,首要使用字段。
+haGoVerifyNum	派送时核对客人独有的IDhaDeliveryLabelNums
+haDeliveryLabelNums	揽收时凭核对HA_deliveryLabelNums子单的编号,多个用竖划线分隔,如1234567893-N01|1234567893-D02
+haOthers	JOSN格式用作储存参考资料,地区以大数据方式捞取数据,每日产出派送结果报表明细
+monthlyCustomerId	下单月结卡号,用于标识下单客户的月结卡号,不用于结算,应用场景:到付折扣
+* */
+/*
+* 确认/取消订单
+* 扩展字段备注
+attrName	        attrVal
+attr001
+attr002
+userId	            商家或合作店铺id 丰网业务
+branchCode	        丰网合作网点(丰网必填) 丰网业务
+branchAddressId	    丰网合作地址id 丰网业务
+channelCode	        渠道编码 丰网业务
+* */
+@Data
+public class SFExtraInfo {
+//#	属性名	类型(约束)	必填	默认值	描述
+//1	attrName	String(256)	否		扩展字段说明:attrName为字段定义, 具体如下表,value存在attrVal
+    String attrName;
+//2	attrVal	String(1024)	否		扩展字段值
+    String attrVal;
+}

+ 43 - 0
src/main/java/com/uas/eis/entity/sf/SFRouteLabelData.java

@@ -0,0 +1,43 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFRouteLabelData {
+//#	属性名	类型(约束)	必填	描述
+//1	waybillNo	String(30)	否	运单号
+    String waybillNo;
+//2	sourceTransferCode	String(60)	否	原寄地中转场
+//3	sourceCityCode	String(60)	否	原寄地城市代码
+//4	sourceDeptCode	String(60)	否	原寄地网点代码
+//5	sourceTeamCode	String(60	否	原寄地单元区域
+//6	destCityCode	String(60)	否	目的地城市代码, eg:755
+//7	destDeptCode	String(60)	否	目的地网点代码, eg:755AQ
+//8	destDeptCodeMapping	String(60)	否	目的地网点代码映射码
+//9	destTeamCode	String(60)	否	目的地单元区域, eg:001
+//10	destTeamCodeMapping	String(60)	否	目的地单元区域映射码
+//11	destTransferCode	String(60)	否	目的地中转场
+//12	destRouteLabel	String(200)	是	若返回路由标签,则此项必会返回。如果手打是一段码,检查是否地址异常。打单时的路由标签信息如果是大网的路由标签,这里的值是目的地网点代码,如果 是同城配的路由标签,这里的值是根据同城配的设置映射出来的值,不同的配置结果会不一样,不能根据-符号切分(如:上海同城配,可能是:集散点-目的地网点-接驳点,也有可能是目的地网点代码-集散点-接驳点)
+//13	proName	String(60)	否	产品名称 对应RLS:pro_name
+//14	cargoTypeCode	String(30)	否	快件内容: 如:C816、SP601
+//15	limitTypeCode	String(30)	否	时效代码, 如:T4
+//16	expressTypeCode	String(30)	否	产品类型,如:B1
+//17	codingMapping	String(60)	是	入港映射码 eg:S10 地址详细必会返回
+//18	codingMappingOut	String(60)	否	出港映射码
+//19	xbFlag	String(30)	否	XB标志 0:不需要打印XB 1:需要打印XB
+//20	printFlag	String(60)	否	打印标志 返回值总共有9位,每位只 有0和1两种,0表示按丰密 面单默认的规则,1是显示, 顺序如下,如111110000 表示打印寄方姓名、寄方 电话、寄方公司名、寄方 地址和重量,收方姓名、收 方电话、收方公司和收方 地址按丰密面单默认规则 1:寄方姓名 2:寄方电话 3:寄方公司名 4:寄方地址 5:重量 6:收方姓名 7:收方电话 8:收方公司名 9:收方地址
+//21	twoDimensionCode	String(600)	否	二维码 根据规则生成字符串信息, 格式为MMM={‘k1’:’(目的 地中转场代码)’,‘k2’:’(目的 地原始网点代码)’,‘k3’:’(目 的地单元区域)’,‘k4’:’(附件 通过三维码(express_type_code、 limit_type_code、 cargo_type_code)映射时效类型)’,‘k5’:’(运单 号)’,‘k6’:’(AB标识)’,‘k7’:’( 校验码)’}
+//22	proCode	String(30)	否	时效类型: 值为二维码中的K4
+//23	printIcon	String(100)	否	打印图标,根据托寄物判断需 要打印的图标(重货,蟹类,生鲜,易碎,Z标) 返回值有8位,每一位只有0和1两种, 0表示按运单默认的规则, 1表示显示。后面两位默认0备用。 顺序如下:重货,蟹类,生鲜,易碎,医药类,Z标,酒标,0 如:00000000表示不需要打印重货,蟹类,生鲜,易碎 ,医药,Z标,酒标,备用
+//24	abFlag	String(30)	否	AB标
+//25	waybillIconList	List	否	面单图标
+//25	errMsg	String(1000)	否	查询出现异常时返回信息。 返回代码: 0 系统异常 1 未找到面单
+//26	destPortCode	String(100)	否	目的地口岸代码
+//27	destCountry	String(50)	否	目的国别(国别代码如:JP)
+//28	destPostCode	String(100)	否	目的地邮编
+//29	goodsValueTotal	String(30)	否	总价值(保留两位小数,数字类型,可补位)
+//30	currencySymbol	String(30)	否	币种
+//31	goodsNumber	String(20)	否	件数
+//32	destAddrKeyWord	String(100)	否	目的地地址关键词
+//33	noToDoorPayment	String(1)	否	乡村件不上门标签
+}

+ 13 - 0
src/main/java/com/uas/eis/entity/sf/SFRouteLabelInfo.java

@@ -0,0 +1,13 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFRouteLabelInfo {
+//1	code	String(30)	是	返回调用结果,1000:调用成功; 其他调用失败
+    String code;
+//2	routeLabelData	routeLabelData	是	路由标签数据详细数据,除少量特殊场景用户外,其余均会返回
+    SFRouteLabelData routeLabelData;
+//3	message	String(1000)	否	失败异常描述
+    String message;
+}

+ 20 - 0
src/main/java/com/uas/eis/entity/sf/SFServiceResp.java

@@ -0,0 +1,20 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFServiceResp {
+    //#	属性名	类型(约束)	必填	默认值	描述
+    //1	name	String(20)	是		增值服务名,如COD等,支持附录: 《增值服务产品表》
+    String name;
+    //2	value	String(30)	条件		增值服务扩展属性,参考增值 服务传值说明
+    String value;
+    //3	value1	String(30)	条件		增值服务扩展属性
+    String value1;
+    //4	value2	String(30)	条件		增值服务扩展属性2
+    String value2;
+    //5	value3	String(30)	条件		增值服务扩展属性3
+    String value3;
+    //6	value4	String(30)	条件		增值服务扩展属性4
+    String value4;
+}

+ 24 - 0
src/main/java/com/uas/eis/entity/sf/SFWaybillNoInfo.java

@@ -0,0 +1,24 @@
+package com.uas.eis.entity.sf;
+
+import lombok.Data;
+
+@Data
+public class SFWaybillNoInfo {
+//#	属性名	类型(约束)	必填	默认值	描述
+//1	waybillType	Number (1)	否		运单号类型1:母单 2 :子单 3 : 签回单
+    Integer waybillType;
+//2	waybillNo	String(15)	否		运单号
+    String waybillNo;
+//3	boxNo	String(64)	否		箱号
+    String boxNo;
+//4	length	Number (16,3)	否		长(cm)
+    Double length;
+//5	width	Number (16,3)	否		宽(cm)
+    Double width;
+//6	height	Number (16,2)	否		高(cm)
+    Double height;
+//7	weight	Number (16,2)	否		重量(kg)
+    Double weight;
+//9	volume	Number (16,2)	否		体积(立方厘米)
+    Double volume;
+}

+ 3 - 4
src/main/java/com/uas/eis/service/ERPService.java

@@ -11,8 +11,7 @@ import java.util.Map;
  * @date 2021-12-06 18:25
  */
 public interface ERPService {
-    Map<String, Object> createSticker(String master, Integer id);
-    Map<String, Object> createSticker2(String master, Integer id);
-    Map<String, Object> getToken(Map<String, String> map);
-    Map<String, Object> updateStickerByList(String master, Integer id,Map<String, String> map,List<Map<String,Object>> updateLists);
+    Map<String, Object> creatSFOrder(String master, Integer id,String emCode);
+
+    Map<String, Object> cancelSFOrder(String master, Integer id, String emCode);
 }

+ 282 - 390
src/main/java/com/uas/eis/service/Impl/ERPServiceImpl.java

@@ -1,457 +1,349 @@
 package com.uas.eis.service.Impl;
 
+import com.sf.csim.express.service.CallExpressServiceTools;
+import com.sf.csim.express.service.HttpClientUtil;
+import com.sf.csim.express.service.IServiceCodeStandard;
+import com.sf.csim.express.service.code.ExpressServiceCodeEnum;
 import com.uas.eis.core.config.SpObserver;
-import com.uas.eis.core.support.TokenProperties;
 import com.uas.eis.dao.*;
+import com.uas.eis.entity.sf.*;
 import com.uas.eis.service.ERPService;
 import com.uas.eis.utils.*;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Service;
 
 import java.util.*;
-import java.util.stream.Collectors;
 
 /**
- * @author koul
- * @email koul@usoftchina.com
- * @date 2021-12-06 18:27
+ * @author wuyx
+ * @email wuyx@usoftchina.com
+ * @date 2024-09-03
  */
 @Service
 public class ERPServiceImpl implements ERPService {
     private final Logger logger = LoggerFactory.getLogger(this.getClass());
-    private static Map<String, String> tokenConfig = TokenProperties.getAllProperty();
-
     @Autowired
     private BaseDao baseDao;
-
     @Override
-    public Map<String, Object> createSticker(String master, Integer id) {
+    public Map<String, Object> creatSFOrder(String master, Integer id,String emCode) {
         Map<String,Object> retMap = new HashMap<>();
         retMap.put("success",true);
-        logger.info("createSticker-Begin:master {} id {}",master,id);
+        logger.info("creatSFOrder-Begin:master {} id {}",master,id);
         SpObserver.putSp(master);
-        SqlRowList docLoist = baseDao.queryForRowSet("select cd_cpn,min(CD_DC) ztcnno,pr_capacity zzbsmount,pr_zxbzs zzxsmount,pr_zxbzs zbzsmount" +
-                " ,sum(CD_QTY) zmount,cd_wflag zwidth,cd_remark zremark,min(cd_lotno) zzstz " +
-                "from CatlDocDetail left join product on pr_code = CD_PRCODE " +
-                "where cd_caid = ? and CD_PANID is null and nvl(pr_capacity,0)>0 " +
-                "group by CD_CPN,pr_capacity,pr_zxbzs,cd_wflag,cd_remark order by min(cd_detno)",id);
-        if(!docLoist.hasNext()){
-//            System.out.println("no docLoist!");
-            retMap.put("success",false);
-            retMap.put("message","没有需要对接的明细.");
-            logger.info("createSticker-F:master {} id {} no docLoist!",master,id);
-        }
-        Object[] obs = baseDao.getFieldsDataByCondition("YITOA_DATACENTER.dock_catl_config A "
-                , new String[]{"URL_","deipaaskeyauth","appKey", "appSecret","VENDCODE"}
-                , "username='"+master+"' and A.ENVTYPE = (SELECT B.ENVTYPE FROM YITOA_DATACENTER.DOCK_CATL_EVCONFIG B WHERE A.username = B.username )");
-        String url = String.valueOf(obs[0]);
-        String deipaaskeyauth = String.valueOf(obs[1]);
-        String vendcode = String.valueOf(obs[4]);
-        Map<String,String> map = new HashMap<>();
-        map.put("url",url);
-        map.put("deipaaskeyauth",deipaaskeyauth);
-        map.put("appKey",String.valueOf(obs[2]));
-        map.put("appSecret",String.valueOf(obs[3]));
-        Map<String,Object> tokenMap = getToken(map);
-        if(!(boolean)tokenMap.get("success")){
-            return tokenMap;
-        }
-        String action="/SNC/outer_SNC_createSticker?sap-client=810&interfacename=ZIRFC_TP2SNC_CREATESTICKER";
-        String deipaasjwt = "Bearer "+tokenMap.get("token");
-        map.put("deipaasjwt",deipaasjwt);
-        StringBuffer errMsg = new StringBuffer();
-        for (Map<String,Object> docMap: docLoist.getResultList()) {
-            try {
-                // CD_CPN,pr_capacity,pr_zxbzs,cd_wflag,cd_remark
-                String matnr = String.valueOf(docMap.get("cd_cpn"));
-                String zwidth = StringUtil.nvl(docMap.get("zwidth"),"");
-                String zremark = StringUtil.nvl(docMap.get("zremark"),"");
+        SqlRowList outMsg = baseDao.queryForRowSet(" select pi_inoutno,pi_dockingstatus,pi_title,pi_address,pi_purposename,pi_expresscode,pi_dockingcode " +
+                        " from prodinout where pi_id = ? ",id);
+        if(outMsg.next()){
+            if(outMsg.getGeneralString("pi_dockingstatus").equals("已创建")){
+                retMap.put("success",false);
+                retMap.put("message","出货单已创建顺发订单.");
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
+            }
+            Object[] obs = baseDao.getFieldsDataByCondition("JYX_ZS.DOCK_SF_CONFIG A "
+                    , new String[]{"CALL_URL","CLIENT_CODE","CHECK_WORD","ENABLE_"}, "username='"+master+"' and A.ENABLE_ = 1");
+            if(!StringUtil.hasText(obs[0])){
+                retMap.put("success",false);
+                retMap.put("message","请联系管理员配置创建URL.");
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
+            }
+            if(!StringUtil.hasText(obs[1])){
+                retMap.put("success",false);
+                retMap.put("message","请联系管理员配置丰桥平台顾客编码.");
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
+            }
+            if(!StringUtil.hasText(obs[2])){
+                retMap.put("success",false);
+                retMap.put("message","请联系管理员配置丰桥平台校验码.");
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
+            }
+            boolean prodFlag = (Integer.valueOf(obs[3].toString())!=0);
+            Object emName = baseDao.getFieldDataByCondition("employee" , "em_name", "em_code='"+emCode+"'");
+            if(emName == null){
+                emName = "管理员("+emCode+")";
+            }
+            String inoutNo = outMsg.getGeneralString("pi_inoutno");
+            String orderCode = outMsg.getGeneralString("pi_dockingcode");
+            if(orderCode.length()>0){
+                orderCode=inoutNo+"-"+(Integer.valueOf(orderCode.split("-")[1])+1);
+            }else {
+                orderCode=inoutNo+"-1";
+            }
+            String CLIENT_CODE = obs[1].toString();  //此处替换为您在丰桥平台获取的顾客编码
+            //沙箱环境的地址 -PRO https://sfapi-sbox.sf-express.com/std/service
+            //生产环境的地址 -PRO https://sfapi.sf-express.com/std/service
+            String CALL_URL = obs[0].toString();
+            //此处替换为您在丰桥平台获取的校验码 生产环境 "GgO0UoyQ5FssNLItii3olo63bQ80ErAE" 沙箱环境 "rMBhSYRa9OtUPkfX5mow01NlxDWtI411"
+            String CHECK_WORD = obs[2].toString();
+            String monthlyCard = "7551234567";
+            if(prodFlag){
+                monthlyCard = baseDao.getDBSetting("ProdInOut!Sale","monthlyCard");
+            }
+            //寄件人
+            Object[] en = baseDao.getFieldsDataByCondition("enterprise" , new String[]{"EN_NAME","EN_DELIVERADDR"}, "1=1");
+            String sendCop = en[0].toString();
+            String sendAddr = en[1].toString();
+            String sendMan = baseDao.getDBSetting("ProdInOut!Sale","sendMan");
+            String sendMobile = baseDao.getDBSetting("ProdInOut!Sale","sendMobile");
 
-                Map<String,Object> paraMap=new HashMap<>();
-                paraMap.put("matnr",matnr);//物料号:客户料号
-                paraMap.put("ztcnno",docMap.get("ztcnno"));//制造日期: 取最小DC
-                paraMap.put("zzstz",docMap.get("zzstz"));//供应商批次: 用最小批次作为虚拟批次
-//				paraMap.put("zeiar",docMap.get("zeiar"));//版本
-				paraMap.put("zwidth",zwidth);//宽度
-                paraMap.put("zmount",docMap.get("zmount"));//本次生产总数量
-				paraMap.put("zzbsmount",docMap.get("zzbsmount"));//栈板容量
-                paraMap.put("zzxsmount",docMap.get("zzxsmount"));//纸箱容量
-                paraMap.put("zbzsmount",docMap.get("zbzsmount"));//包装袋容量
-				paraMap.put("zremark",zremark);//备注
-                paraMap.put("partner",vendcode);//供应商编码 固定值
-                HttpUtil.Response response = HttpUtil.doPost(url+action, JacksonUtil.toJson(paraMap), deipaaskeyauth,deipaasjwt);
-                if (response.getStatusCode() == HttpStatus.OK.value()){
-                    String res = response.getResponseText();
-                    if(res!=null && !"".equals(res)){
-//                        System.out.println("res:"+res);
-                        Map<String,Object> resData = JacksonUtil.fromJson(res);
-                        if("S".equals(String.valueOf(resData.get("e_type")))){
-                            List<Map<String,Object>> outdata = (List) resData.get("outdata");
-//                            System.out.println("outdata.size:"+outdata.size());
-                            //栈ID
-//                            List<Map<String,Object>> palletIdList = outdata.stream().filter(od->{
-//                                return (Double.valueOf(od.get("levels").toString().trim()) == 0);
-//                            }).collect(Collectors.toList());
-                            //箱ID
-                            List<Map<String,Object>> boxIdList = outdata.stream().filter(od->{
-                                return (Double.valueOf(od.get("levels").toString().trim()) == 1);
-                            }).collect(Collectors.toList());
-                            //袋ID
-                            List<Map<String,Object>> panIdList = outdata.stream().filter(od->{
-                                return (Double.valueOf(od.get("levels").toString().trim()) == 2);
-                            }).collect(Collectors.toList());
-                            //更新箱ID、袋ID
-                            List<String> sqls = new ArrayList<>();
-                            // CD_CPN,pr_capacity,pr_zxbzs,cd_wflag,cd_remark
-                            // matnr,zwidth,zremark
-                            SqlRowList updateList = baseDao.queryForRowSet("select cd_id,cd_lotno,cd_dc,nvl(cd_ed,to_char(to_date(cd_dc,'yyyymmdd')+365,'yyyymmdd')) cd_ed from CatlDocDetail " +
-                                    " where cd_caid = "+id+" and CD_PANID is null and CD_CPN = '"+matnr+"' " +
-                                    " and nvl(cd_wflag,' ') = '"+StringUtil.nvl(zwidth," ")+"'" +
-                                    " and nvl(cd_remark,' ') = '"+StringUtil.nvl(zremark," ")+"'" +
-                                    "  order by cd_detno");
-                            List<Map<String,Object>> updateStickerList = new ArrayList<>();
-                            if(panIdList.size() == updateList.getResultList().size()){
-                                for (int i = 0; i < updateList.getResultList().size(); i++) {
-                                    Map<String,Object> updateMap = updateList.getResultList().get(i);
-                                    Map<String,Object> idMap = panIdList.get(i);
-                                    String panId = idMap.get("zalt_id").toString();
-                                    String boxId = idMap.get("zalt_id_upper").toString();
-                                    //获取栈ID
-                                    String palletId = "";
-                                    Optional<Map<String,Object>> boxMsg = boxIdList.stream()
-                                            .filter(bMap -> bMap.get("zalt_id").equals(boxId))
-                                            .findFirst();
-                                    if(boxMsg.isPresent()&&!boxMsg.get().isEmpty()){
-                                        palletId = boxMsg.get().get("zalt_id_upper").toString();
-                                    }
-                                    sqls.add("update CatlDocDetail set cd_palletid='"+StringUtil.nvl(palletId,"")+"' ,CD_PANID='"+panId+"',CD_BOXID='"+boxId+"'" +
-                                            ",cd_batchid='"+idMap.get("batch_id")+"',cd_wbs='"+idMap.get("wbs")+"' " +
-                                            "where cd_id = "+updateMap.get("cd_id"));
-                                    if(!updateMap.get("cd_lotno").equals(idMap.get("prtbatchid"))){
-                                        Map<String,Object> updatePanMap = new HashMap<>();
-                                        updatePanMap.put("matnr",matnr);//物料号
-                                        updatePanMap.put("zalt_id",panId);//贴纸ID
-                                        updatePanMap.put("prtbatchid",updateMap.get("cd_lotno"));//供应商批次
-                                        updatePanMap.put("manufacturing_date",updateMap.get("cd_dc"));//生产日期
-                                        updatePanMap.put("atlyx",updateMap.get("cd_ed"));//有效日期
-                                        updateStickerList.add(updatePanMap);
-                                        Map<String,Object> updateBoxMap = new HashMap<>();
-                                        updateBoxMap.put("matnr",matnr);//物料号
-                                        updateBoxMap.put("zalt_id",boxId);//贴纸ID
-                                        updateBoxMap.put("prtbatchid",updateMap.get("cd_lotno"));//供应商批次
-                                        updateBoxMap.put("manufacturing_date",updateMap.get("cd_dc"));//生产日期
-                                        updateBoxMap.put("atlyx",updateMap.get("cd_ed"));//有效日期
-                                        updateStickerList.add(updateBoxMap);
-                                    }
-                                }
-                                // 更新栈ID、箱ID、袋ID
-                                if(sqls.size()>0){
-                                    baseDao.execute(sqls);
-                                    //第二个接口 更新供应商批次
-                                    Map<String,Object> updateStickerMap = updateStickerByList(master, id,map,updateStickerList);
-                                    if(!(boolean) updateStickerMap.get("success")){
-                                        errMsg.append("更新供应商批次失败:客户料号:"+matnr).append(updateStickerMap.get("message")).append("</br>");
+            IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER; //下订单
+            CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
+            Map<String, String> params = new HashMap<String, String>();
+            String timeStamp = String.valueOf(System.currentTimeMillis());
+            String msgData = "";
+            SFCreatOrderReq sfOrder = new SFCreatOrderReq();
+            sfOrder.setOrderId(orderCode);
+            sfOrder.setMonthlyCard(monthlyCard);
+            //寄件方信息
+            List<SFContactInfo> contactInfoList = new ArrayList<>();
+            SFContactInfo sendInfo = new SFContactInfo();
+            sendInfo.setContactType(1);
+            sendInfo.setCompany(sendCop);
+            sendInfo.setContact(sendMan);
+            sendInfo.setMobile(sendMobile);
+            sendInfo.setAddress(sendAddr);
+            contactInfoList.add(sendInfo);
+            //到件方信息
+            SFContactInfo receiveInfo = new SFContactInfo();
+            receiveInfo.setContactType(2);
+            receiveInfo.setCompany(outMsg.getGeneralString("pi_title"));
+            receiveInfo.setContact(outMsg.getGeneralString("pi_purposename"));
+            receiveInfo.setMobile(outMsg.getGeneralString("pi_expresscode"));
+            receiveInfo.setAddress(outMsg.getGeneralString("pi_address"));
+            contactInfoList.add(receiveInfo);
+            sfOrder.setContactInfoList(contactInfoList);
+            List<SFCargoDetail> cargoDetails = new ArrayList<>();
+            SqlRowList outList = baseDao.queryForRowSet(" select pr_detail,pr_unit,sum(pd_outqty) outqty from prodiodetail left join product on pr_code = pd_prodcode where pd_piid = ? and pr_detail is not null group by pr_detail,pr_unit",id);
+            while (outList.next()){
+                SFCargoDetail cargoDetail = new SFCargoDetail();
+                cargoDetail.setName(outList.getGeneralString("pr_detail"));
+                cargoDetail.setUnit(outList.getGeneralString("pr_unit"));
+                cargoDetail.setCount(outList.getGeneralDouble("outqty"));
+                cargoDetails.add(cargoDetail);
+            }
+            sfOrder.setCargoDetails(cargoDetails);
+            msgData = FlexJsonUtil.toJsonDeep(sfOrder);
+            try {
+                params.put("partnerID", CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
+                params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
+                params.put("serviceCode",standardService.getCode());// 接口服务码
+                params.put("timestamp", timeStamp);
+                params.put("msgData", msgData);
+                params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,CHECK_WORD));
+                long startTime = System.currentTimeMillis();
+                System.out.println("====调用实际请求:" + params);
+                String result = HttpClientUtil.post(CALL_URL, params);
+                System.out.println("====调用丰桥的接口服务代码:" + String.valueOf(standardService.getCode()) + " 接口耗时:"+ String.valueOf(System.currentTimeMillis()-startTime)+"====");
+                System.out.println("===调用地址 ==="+CALL_URL);
+                System.out.println("===顾客编码 ==="+CLIENT_CODE);
+                System.out.println("===返回结果:" +result);
+                SFApiResp sfApiResp = FlexJsonUtil.fromJson(result, SFApiResp.class);
+                if(sfApiResp!=null){
+                    if("A1000".equals(sfApiResp.getApiResultCode())){
+                        String apiResultData = sfApiResp.getApiResultData();
+                        SFCreatOrderResp sfApiRespData =  FlexJsonUtil.fromJson(apiResultData, SFCreatOrderResp.class);
+                        if(sfApiRespData.isSuccess()){
+                            SFCreateOrder sfOrderResp =  sfApiRespData.getMsgData();
+                            StringBuffer waybillNo = new StringBuffer();
+                            if(!CollectionUtil.isEmpty(sfOrderResp.getWaybillNoInfoList())){
+                                for (SFWaybillNoInfo sfWaybillNoInfoResp:sfOrderResp.getWaybillNoInfoList()){
+//                                    System.out.println("顺丰物流单号: ====="+sfWaybillNoInfoResp.getWaybillNo());
+                                    if(waybillNo.length()>0){
+                                        waybillNo.append(",");
                                     }
+                                    waybillNo.append(sfWaybillNoInfoResp.getWaybillNo());
                                 }
-                            }else {
-                                errMsg.append("条码创建数与实际不一致,型号:"+matnr).append("创建数:"+panIdList.size()+",待更新数量:"+updateList.getResultList().size()).append("</br>");
                             }
-                        }else {
-                            if(StringUtil.hasText(resData.get("e_message"))){
-                                errMsg.append("客户料号:"+matnr).append(resData.get("e_message")).append("</br>");
+                            if(waybillNo.length()>0){
+                                baseDao.execute("update prodinout set pi_dockingcode=?,pi_logisticscode = ?,pi_dockingstatus='已创建' where pi_id = ?",orderCode,waybillNo.toString(),id);
+                                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','创建成功,顺发单号:"+orderCode+",物流单号:"+waybillNo.toString()+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                             }else {
-                                errMsg.append("客户料号:"+matnr).append("创建条码失败").append("</br>");
+                                retMap.put("message","创建失败:["+sfApiRespData.getErrorCode()+"]"+sfApiRespData.getErrorMsg());
+                                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
+                                retMap.put("success",false);
+                                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                                return retMap;
                             }
+                        }else {
+                            retMap.put("message","创建失败:["+sfApiRespData.getErrorCode()+"]"+sfApiRespData.getErrorMsg());
+                            baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                    "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
+                            retMap.put("success",false);
+                            logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                            return retMap;
                         }
-                    }else{
-                        logger.info("getToken-F:No ResponseText");
+                    }else {
+//                        System.out.println("code:"+sfApiResp.getApiResultCode()+"===apiResponseID:"+sfApiResp.getApiResponseID()+"===apiErrorMsg:"+sfApiResp.getApiErrorMsg());
+                        retMap.put("message","创建失败:["+sfApiResp.getApiResultCode()+"]"+sfApiResp.getApiErrorMsg());
+                        baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                         retMap.put("success",false);
-                        retMap.put("message", "No ResponseText");
+                        logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                        return retMap;
                     }
-                }else {
-                    logger.info("createSticker-F:StatusCode {} ResponseText {}",response.getStatusCode(),response.getResponseText());
-                    retMap.put("success",false);
-                    retMap.put("message", response.getStatusCode()+":"+response.getResponseText());
                 }
             }catch (Exception e){
                 e.printStackTrace();
+                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','创建失败:"+(StringUtil.nvl(e.getMessage(),""))+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                 retMap.put("success",false);
-                retMap.put("message","创建条码异常。");
+                retMap.put("message","创建失败"+(StringUtil.nvl(e.getMessage(),"")));
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
             }
-        }
-        if(errMsg.length()>0){
-//            System.out.println("errMsg:"+errMsg.toString());
-            retMap.put("success",false);
-            retMap.put("message","对接失败:</br>"+errMsg.toString());
         }else {
-            baseDao.execute("update CatlDoc set CA_DOCSTATE=1 where ca_id = "+id);
+            retMap.put("success",false);
+            retMap.put("message","没有需要创建的出货单.");
+            logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+            return retMap;
         }
-        logger.info("createSticker-End:master {} id {} retMap {}",master,id,retMap.toString());
+        logger.info("creatSFOrder-End:master {} id {}",master,id);
+        retMap.put("message","创建成功。");
         return retMap;
     }
 
     @Override
-    public Map<String, Object> createSticker2(String master, Integer id) {
+    public Map<String, Object> cancelSFOrder(String master, Integer id, String emCode) {
         Map<String,Object> retMap = new HashMap<>();
         retMap.put("success",true);
-        logger.info("createSticker-Begin:master {} id {}",master,id);
+        logger.info("cancelSFOrder-Begin:master {} id {}",master,id);
         SpObserver.putSp(master);
-        SqlRowList docLoist = baseDao.queryForRowSet(
-                " select CD_CPN matnr,CD_DC ztcnno,pr_capacity zzbsmount,pr_zxbzs zzxsmount,pr_zxbzs zbzsmount " +
-                        "  ,sum(CD_QTY) zmount,cd_wflag zwidth,cd_lotno zzstz " +
-                        ",cd_newboxcode||(case when cd_remark is not null then ' '||cd_remark else '' end) zremark,count(1) codecount " +
-                " from CatlDocDetail left join product on pr_code = CD_PRCODE " +
-                " where cd_caid = ? and CD_PANID is null and nvl(pr_capacity,0)>0 " +
-                " group by CD_CPN,CD_DC,pr_capacity,pr_zxbzs,cd_lotno,cd_wflag,cd_newboxcode||(case when cd_remark is not null then ' '||cd_remark else '' end)   " +
-                " order by min(cd_detno) ",id);
-        if(!docLoist.hasNext()){
-//            System.out.println("no docLoist!");
-            retMap.put("success",false);
-            retMap.put("message","没有需要对接的明细.");
-            logger.info("createSticker-F:master {} id {} no docLoist!",master,id);
-        }
-        Object[] obs = baseDao.getFieldsDataByCondition("YITOA_DATACENTER.dock_catl_config A "
-                , new String[]{"URL_","deipaaskeyauth","appKey", "appSecret","VENDCODE"}
-                , "username='"+master+"' and A.ENVTYPE = (SELECT B.ENVTYPE FROM YITOA_DATACENTER.DOCK_CATL_EVCONFIG B WHERE A.username = B.username )");
-        String url = String.valueOf(obs[0]);
-        String deipaaskeyauth = String.valueOf(obs[1]);
-        String vendcode = String.valueOf(obs[4]);
-        Map<String,String> map = new HashMap<>();
-        map.put("url",url);
-        map.put("deipaaskeyauth",deipaaskeyauth);
-        map.put("appKey",String.valueOf(obs[2]));
-        map.put("appSecret",String.valueOf(obs[3]));
-        Map<String,Object> tokenMap = getToken(map);
-        if(!(boolean)tokenMap.get("success")){
-            return tokenMap;
-        }
-        String action="/SNC/outer_SNC_createSticker?sap-client=810&interfacename=ZIRFC_TP2SNC_CREATESTICKER";
-        String deipaasjwt = "Bearer "+tokenMap.get("token");
-        map.put("deipaasjwt",deipaasjwt);
-        StringBuffer errMsg = new StringBuffer();
-        for (Map<String,Object> docMap: docLoist.getResultList()) {
-            try {
-                int codeCount = Integer.valueOf(String.valueOf(docMap.get("codecount")));
-                // CD_CPN,pr_capacity,pr_zxbzs,cd_wflag,cd_remark
-                String matnr = String.valueOf(docMap.get("matnr"));
-                String zwidth = StringUtil.nvl(docMap.get("zwidth"),"");
-                String zremark = StringUtil.nvl(docMap.get("zremark"),"");
-                String ztcnno =  String.valueOf(docMap.get("ztcnno"));
-                String zzstz =  String.valueOf(docMap.get("zzstz"));
-                Map<String,Object> paraMap=new HashMap<>();
-                paraMap.put("matnr",matnr);//物料号:客户料号
-                paraMap.put("ztcnno",ztcnno);//制造日期: 取最小DC
-                paraMap.put("zzstz",zzstz);//供应商批次: 用最小批次作为虚拟批次
-//				paraMap.put("zeiar",docMap.get("zeiar"));//版本
-                paraMap.put("zwidth",zwidth);//宽度
-                paraMap.put("zmount",docMap.get("zmount"));//本次生产总数量
-                paraMap.put("zzbsmount",docMap.get("zzbsmount"));//栈板容量
-                paraMap.put("zzxsmount",docMap.get("zzxsmount"));//纸箱容量
-                paraMap.put("zbzsmount",docMap.get("zbzsmount"));//包装袋容量
-                paraMap.put("zremark",zremark);//备注
-                paraMap.put("partner",vendcode);//供应商编码 固定值
+        SqlRowList outMsg = baseDao.queryForRowSet(" select pi_inoutno,pi_dockingstatus,pi_dockingcode from prodinout where pi_id = ? ",id);
+        if(outMsg.next()) {
+            if (!outMsg.getGeneralString("pi_dockingstatus").equals("已创建")) {
+                retMap.put("success", false);
+                retMap.put("message", "出货单尚未创建顺发订单.");
+                logger.info("cancelSFOrder-F:master {} id {} err {}", master, id, retMap.get("message"));
+                return retMap;
+            }
+            Object[] obs = baseDao.getFieldsDataByCondition("JYX_ZS.DOCK_SF_CONFIG A "
+                    , new String[]{"CALL_URL", "CLIENT_CODE", "CHECK_WORD", "ENABLE_"}, "username='" + master + "' and A.ENABLE_ = 1");
+            if (!StringUtil.hasText(obs[0])) {
+                retMap.put("success", false);
+                retMap.put("message", "请联系管理员配置创建URL.");
+                logger.info("cancelSFOrder-F:master {} id {} err {}", master, id, retMap.get("message"));
+                return retMap;
+            }
+            if (!StringUtil.hasText(obs[1])) {
+                retMap.put("success", false);
+                retMap.put("message", "请联系管理员配置丰桥平台顾客编码.");
+                logger.info("cancelSFOrder-F:master {} id {} err {}", master, id, retMap.get("message"));
+                return retMap;
+            }
+            if (!StringUtil.hasText(obs[2])) {
+                retMap.put("success", false);
+                retMap.put("message", "请联系管理员配置丰桥平台校验码.");
+                logger.info("cancelSFOrder-F:master {} id {} err {}", master, id, retMap.get("message"));
+                return retMap;
+            }
+            Object emName = baseDao.getFieldDataByCondition("employee" , "em_name", "em_code='"+emCode+"'");
+            if(emName == null){
+                emName = "管理员("+emCode+")";
+            }
+            String inoutNo = outMsg.getGeneralString("pi_inoutno");
+            String orderCode = outMsg.getGeneralString("pi_dockingcode");
+            String CLIENT_CODE = obs[1].toString();  //丰桥平台获取的顾客编码
+            String CALL_URL = obs[0].toString(); //沙箱环境的地址 -PRO https://sfapi-sbox.sf-express.com/std/service 生产环境的地址 -PRO https://sfapi.sf-express.com/std/service
+            String CHECK_WORD = obs[2].toString(); //丰桥平台获取的校验码 生产环境 "GgO0UoyQ5FssNLItii3olo63bQ80ErAE" 沙箱环境 "rMBhSYRa9OtUPkfX5mow01NlxDWtI411"
 
-                HttpUtil.Response response = HttpUtil.doPost(url+action, JacksonUtil.toJson(paraMap), deipaaskeyauth,deipaasjwt);
-                if (response.getStatusCode() == HttpStatus.OK.value()){
-                    String res = response.getResponseText();
-                    if(res!=null && !"".equals(res)){
-//                        System.out.println("res:"+res);
-                        Map<String,Object> resData = JacksonUtil.fromJson(res);
-                        if("S".equals(String.valueOf(resData.get("e_type")))){
-                            List<Map<String,Object>> outdata = (List) resData.get("outdata");
-//                            System.out.println("outdata.size:"+outdata.size());
-                            //栈ID
-//                            List<Map<String,Object>> palletIdList = outdata.stream().filter(od->{
-//                                return (Double.valueOf(od.get("levels").toString().trim()) == 0);
-//                            }).collect(Collectors.toList());
-                            //箱ID
-                            List<Map<String,Object>> boxIdList = outdata.stream().filter(od->{
-                                return (Double.valueOf(od.get("levels").toString().trim()) == 1);
-                            }).collect(Collectors.toList());
-                            //袋ID
-                            List<Map<String,Object>> panIdList = outdata.stream().filter(od->{
-                                return (Double.valueOf(od.get("levels").toString().trim()) == 2);
-                            }).collect(Collectors.toList());
-                            //更新箱ID、袋ID
-                            List<String> sqls = new ArrayList<>();
-//                            if(outdata.size() != codeCount){
-//                                errMsg.append("条码创建数与实际不一致,型号:"+matnr).append("创建数:"+outdata.size()+",待更新数量:"+codeCount).append("</br>");
-//                                continue;
-//                            }
-//                          CD_CPN matnr,CD_DC ztcnno,cd_wflag zwidth,cd_lotno zzstz,cd_newboxcode||(case when cd_remark is not null then ' '||cd_remark else '' end) zremark,count(1) codecount " +
-                            SqlRowList updateList = baseDao.queryForRowSet("select cd_id from CatlDocDetail " +
-                                    " where cd_caid = "+id+" and CD_PANID is null " +
-                                    " and CD_CPN = '"+matnr+"' " +
-                                    " and nvl(CD_DC,' ') = '"+StringUtil.nvl(ztcnno," ")+"'" +
-                                    " and nvl(cd_wflag,' ') = '"+StringUtil.nvl(zwidth," ")+"'" +
-                                    " and nvl(cd_lotno,' ') = '"+StringUtil.nvl(zzstz," ")+"'" +
-                                    " and cd_newboxcode||(case when cd_remark is not null then ' '||cd_remark else '' end) = '"+StringUtil.nvl(zremark," ")+"'" +
-                                    " order by cd_detno");
-                            if(panIdList.size() != updateList.getResultList().size()){
-                                errMsg.append("条码创建数与实际不一致,型号:"+matnr).append("创建数:"+panIdList.size()+",待更新数量:"+updateList.getResultList().size()).append("</br>");
-                                continue;
-                            }
-                            for (int i = 0; i < updateList.getResultList().size(); i++) {
-                                Map<String,Object> updateMap = updateList.getResultList().get(i);
-                                Map<String,Object> idMap = panIdList.get(i);
-                                String panId = idMap.get("zalt_id").toString();
-                                String boxId = idMap.get("zalt_id_upper").toString();
-                                //获取栈ID
-                                String palletId = "";
-                                Optional<Map<String,Object>> boxMsg = boxIdList.stream()
-                                        .filter(bMap -> bMap.get("zalt_id").equals(boxId))
-                                        .findFirst();
-                                if(boxMsg.isPresent()&&!boxMsg.get().isEmpty()){
-                                    palletId = boxMsg.get().get("zalt_id_upper").toString();
+            IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;//订单取消
+            CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
+            Map<String, String> params = new HashMap<String, String>();
+            String timeStamp = String.valueOf(System.currentTimeMillis());
+            String msgData = "";
+            Map<String,Object> msgDataMap = new HashMap<>();
+            msgDataMap.put("orderId",orderCode);
+            msgDataMap.put("dealType",2);
+            msgData = FlexJsonUtil.toJsonDeep(msgDataMap);
+            try {
+                params.put("partnerID", CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
+                params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
+                params.put("serviceCode",standardService.getCode());// 接口服务码
+                params.put("timestamp", timeStamp);
+                params.put("msgData", msgData);
+                params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,CHECK_WORD));
+                long startTime = System.currentTimeMillis();
+//		System.out.println("====调用请求:" + params.get("msgData"));
+//                System.out.println("====调用实际请求:" + params);
+                String result = HttpClientUtil.post(CALL_URL, params);
+//                System.out.println("====调用丰桥的接口服务代码:" + String.valueOf(standardService.getCode()) + " 接口耗时:"+ String.valueOf(System.currentTimeMillis()-startTime)+"====");
+//                System.out.println("===调用地址 ==="+CALL_URL);
+//                System.out.println("===顾客编码 ==="+CLIENT_CODE);
+//                System.out.println("===返回结果:" +result);
+//		Map<String,Object> resData = JacksonUtil.fromJson(result);
+                SFApiResp sfApiResp = FlexJsonUtil.fromJson(result, SFApiResp.class);
+                if(sfApiResp!=null){
+                    if("A1000".equals(sfApiResp.getApiResultCode())){
+                        String apiResultData = sfApiResp.getApiResultData();
+                        SFCancelOrderResp sfApiRespData =  FlexJsonUtil.fromJson(apiResultData, SFCancelOrderResp.class);
+                        if(sfApiRespData.isSuccess()){
+                            SFCancelOrder sfOrderResp =  sfApiRespData.getMsgData();
+                            StringBuffer waybillNo = new StringBuffer();
+                            if(!CollectionUtil.isEmpty(sfOrderResp.getWaybillNoInfoList())){
+                                for (SFWaybillNoInfo sfWaybillNoInfoResp:sfOrderResp.getWaybillNoInfoList()){
+//                                    System.out.println("顺丰物流单号: ====="+sfWaybillNoInfoResp.getWaybillNo());
+                                    if(waybillNo.length()>0){
+                                        waybillNo.append(",");
+                                    }
+                                    waybillNo.append(sfWaybillNoInfoResp.getWaybillNo());
                                 }
-                                sqls.add("update CatlDocDetail set cd_palletid='"+StringUtil.nvl(palletId,"")+"' ,CD_PANID='"+panId+"',CD_BOXID='"+boxId+"'" +
-                                        ",cd_batchid='"+idMap.get("batch_id")+"',cd_wbs='"+idMap.get("wbs")+"' " +
-                                        "where cd_id = "+updateMap.get("cd_id"));
-                            }
-                            // 更新栈ID、箱ID、袋ID
-                            if(sqls.size()>0){
-//                                System.out.println(sqls);
-                                baseDao.execute(sqls);
                             }
-                        }else {
-                            if(StringUtil.hasText(resData.get("e_message"))){
-                                errMsg.append("客户料号:"+matnr).append(resData.get("e_message")).append("</br>");
+                            if(sfOrderResp.getResStatus()==2){
+                                baseDao.execute("update prodinout set pi_logisticscode = null,pi_dockingstatus=null where pi_id = ?",id);
+                                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','取消顺发订单','取消成功"+(waybillNo.length()>0?",物流单号: "+waybillNo.toString():"")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                             }else {
-                                errMsg.append("客户料号:"+matnr).append("创建条码失败").append("</br>");
-                            }
-                        }
-                    }else{
-                        logger.info("getToken-F:No ResponseText");
-                        retMap.put("success",false);
-                        retMap.put("message", "No ResponseText");
-                    }
-                }else {
-                    logger.info("createSticker-F:StatusCode {} ResponseText {}",response.getStatusCode(),response.getResponseText());
-                    retMap.put("success",false);
-                    retMap.put("message", response.getStatusCode()+":"+response.getResponseText());
-                }
-            }catch (Exception e){
-                e.printStackTrace();
-                retMap.put("success",false);
-                retMap.put("message","创建条码异常。");
-            }
-        }
-        if(errMsg.length()>0){
-//            System.out.println("errMsg:"+errMsg.toString());
-            retMap.put("success",false);
-            retMap.put("message","对接失败:</br>"+errMsg.toString());
-        }else {
-            baseDao.execute("update CatlDoc set CA_DOCSTATE=1 where ca_id = "+id);
-        }
-        logger.info("createSticker-End:master {} id {} retMap {}",master,id,retMap.toString());
-        return retMap;
-    }
-    @Override
-    public Map<String, Object> getToken(Map<String, String> map) {
-        Map<String, Object> retMap = new HashMap<>();
-        retMap.put("success",true);
-        String url = map.get("url");
-        String deipaaskeyauth = map.get("deipaaskeyauth");
-        String appKey = map.get("appKey");
-        String appSecret = map.get("appSecret");
-        logger.info("getToken-begin: url {} ,deipaaskeyauth {},appKey {},appSecret {} ", url,deipaaskeyauth,appKey,appSecret);
-        String action="/ipaas/ipaas_getJwtToken";
-        Map<String,Object> paraMap=new HashMap<>();
-        paraMap.put("appKey",appKey);
-        paraMap.put("appSecret",appSecret);
-        paraMap.put("time",60);
-        try {
-            HttpUtil.Response response =HttpUtil.doPost(url+action, JacksonUtil.toJson(paraMap), deipaaskeyauth,"");
-            if (response.getStatusCode() == HttpStatus.OK.value()){
-                String res = response.getResponseText();
-                if(res!=null && !"".equals(res)){
-                    Map<String,Object> resMap = JacksonUtil.fromJson(res);
-                    logger.info("getToken-S: {} ", String.valueOf(resMap.get("accessToken")));
-                    retMap.put("token", String.valueOf(resMap.get("accessToken")));
-                }else{
-                    logger.info("getToken-F:No ResponseText");
-                    retMap.put("success",false);
-                    retMap.put("message", "No ResponseText");
-                }
-            }else {
-                logger.info("getToken-F:StatusCode {} ResponseText {}",response.getStatusCode(),response.getResponseText());
-                retMap.put("success",false);
-                retMap.put("message", response.getStatusCode()+":"+response.getResponseText());
-            }
-        }catch (Exception e){
-            e.printStackTrace();
-            retMap.put("success",false);
-            retMap.put("message", "对接异常");
-        }
-        return retMap;
-    }
-
-    @Override
-    public Map<String, Object> updateStickerByList(String master, Integer id,Map<String, String> map,List<Map<String,Object>> updateLists) {
-        Map<String, Object> retMap = new HashMap<>();
-        retMap.put("success",true);
-        if(CollectionUtil.isEmpty(updateLists)){
-            return retMap;
-        }
-        String url = map.get("url");
-        String deipaaskeyauth = map.get("deipaaskeyauth");
-        String appKey = map.get("appKey");
-        String appSecret = map.get("appSecret");
-        String deipaasjwt = map.get("deipaasjwt");
-        logger.info("updateSticker-begin: url {} ,deipaaskeyauth {},appKey {},appSecret {},deipaasjwt {} ", url,deipaaskeyauth,appKey,appSecret,deipaasjwt);
-        String action="/SNC/outer_SNC_updateGyspc?sap-client=810&interfacename=ZIRFC_TP2SNC_UPDATEGYSPC";
-        Map<String,Object> paraMap=new HashMap<>();
-        paraMap.put("inputdata",updateLists);
-        StringBuffer errMsg = new StringBuffer();
-        try {
-            HttpUtil.Response response =HttpUtil.doPost(url+action, JacksonUtil.toJson(paraMap), deipaaskeyauth,deipaasjwt);
-            if (response.getStatusCode() == HttpStatus.OK.value()){
-                String res = response.getResponseText();
-                if(res!=null && !"".equals(res)){
-                    Map<String,Object> resMap = JacksonUtil.fromJson(res);
-                    if(StringUtil.hasText(resMap.get("OUTPUTDATA"))){
-                        if(StringUtil.hasText(String.valueOf(resMap.get("OUTPUTDATA")))){
-                            List<Map<String,Object>> outputdataList = (List) resMap.get("OUTPUTDATA");
-                            for (Map<String,Object> outputdataMap:outputdataList) {
-                                if(!"S".equals(outputdataMap.get("e_msgtype"))){
-                                    errMsg.append("条码:").append(outputdataMap.get("zalt_id")).append(",原因:").append(outputdataMap.get("e_msg")).append("</br>");
-                                    baseDao.execute("update CatlDocDetail set cd_errmsg='"+outputdataMap.get("e_msg")+"' where cd_caid = "+id+" and cd_panid = '"+outputdataMap.get("zalt_id")+"'");
+                                if(sfOrderResp.getResStatus()==1){
+                                    retMap.put("message","取消失败:客户订单号与顺丰运单不匹配");
+                                }else {
+                                    retMap.put("message","取消失败:["+sfOrderResp.getResStatus()+"]");
                                 }
+                                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','取消顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
+                                retMap.put("success",false);
+                                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                                return retMap;
                             }
                         }else {
-                            logger.info("updateSticker-F:No ResponseText");
+                            baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                    "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','取消顺发订单','取消失败:["+sfApiRespData.getErrorCode()+"]"+sfApiRespData.getErrorMsg()+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                             retMap.put("success",false);
-                            retMap.put("message", "No outPutData");
+                            retMap.put("message","取消失败:["+sfApiRespData.getErrorCode()+"]"+sfApiRespData.getErrorMsg());
+                            logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                            return retMap;
                         }
                     }else {
-                        logger.info("updateSticker-F:No ResponseText");
+                        retMap.put("message","创建失败:["+sfApiResp.getApiResultCode()+"]"+sfApiResp.getApiErrorMsg());
+                        baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                                "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','创建顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                         retMap.put("success",false);
-                        retMap.put("message", "No ResponseText");
+                        logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                        return retMap;
                     }
-                }else{
-                    logger.info("updateSticker-F:No ResponseText");
-                    retMap.put("success",false);
-                    retMap.put("message", "No ResponseText");
                 }
-            }else {
-                logger.info("updateSticker-F:StatusCode {} ResponseText {}",response.getStatusCode(),response.getResponseText());
+            }catch (Exception e){
+                e.printStackTrace();
+                retMap.put("message","取消失败"+(StringUtil.nvl(e.getMessage(),"")));
+                baseDao.execute("INSERT INTO MESSAGELOG(ML_ID, ML_DATE, ML_MAN, ML_CONTENT, ML_RESULT, ML_SEARCH, CODE) " +
+                        "values( MESSAGELOG_SEQ.nextval,SYSDATE,'"+emName+"','取消顺发订单','"+retMap.get("message")+"','ProdInOut!Sale|pi_id="+id+"','"+inoutNo+"')");
                 retMap.put("success",false);
-                retMap.put("message", response.getStatusCode()+":"+response.getResponseText());
+                logger.info("creatSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+                return retMap;
             }
-        }catch (Exception e){
-            e.printStackTrace();
-            retMap.put("success",false);
-            retMap.put("message", "对接异常");
-        }
-        if(errMsg.length()>0){
+        }else {
             retMap.put("success",false);
-            retMap.put("message",errMsg.toString());
+            retMap.put("message","没有需要操作的出货单.");
+            logger.info("cancelSFOrder-F:master {} id {} err {}",master,id,retMap.get("message"));
+            return retMap;
         }
+        logger.info("cancelSFOrder-End:master {} id {}",master,id);
+        retMap.put("message","取消成功。");
         return retMap;
     }
-
-
 }

+ 0 - 38
src/main/java/nuonuo/open/sdk/demo/OpenApi.java

@@ -1,38 +0,0 @@
-package nuonuo.open.sdk.demo;
-
-import java.util.UUID;
-
-import nuonuo.open.sdk.NNOpenSDK;
-
-/**
- * 请求Api
- * 
- *【这是一个Eclipse工程, JDK支持1.7+】
- */
-public class OpenApi {
-    
-    /**
-     * 请求开放平台api
-     * 
-     * 请求地址, 详见 https://open.nuonuo.com/#/dev-doc/sdk-usage
-     */
-    public void requestApi() {
-    	// 参数配置
-    	String taxnum = "23***789";//授权企业税号, 商户填""
-    	String appKey = "填写应用的appKey";
-    	String appSecret = "填写应用的appSecret";
-    	String method = "填写API方法名";
-    	String token = "填写访问令牌,可通过OpenToken.java获取";
-    	String content = "填写API私有请求参数, 标准JSON格式";
-    	String url = "https://sdk.nuonuo.com/open/v1/services";// 票据识别请使用https://sdk.nuonuo.com/open/v2/ocr
-    	String senid = UUID.randomUUID().toString().replace("-", ""); // 唯一标识,由企业自己生成32位随机码
-    	
-    	// 接口调用
-    	NNOpenSDK sdk = NNOpenSDK.getIntance();
-        String json = sdk.sendPostSyncRequest(url, senid, appKey, appSecret, token, taxnum, method, content);
-        
-        // 响应报文解析
-        System.out.println("\n\n\n【API请求】");
-    	System.out.println(json);
-    }
-}

+ 0 - 72
src/main/java/nuonuo/open/sdk/demo/OpenToken.java

@@ -1,72 +0,0 @@
-package nuonuo.open.sdk.demo;
-
-import nuonuo.open.sdk.NNOpenSDK;
-
-/**
- * 获取Token
- * 
- * 【这是一个Eclipse工程, JDK支持1.7+】
- */
-public class OpenToken {
-   
-    /**
-     * 商户获取授权码
-     * 
-     * 辅助页面 https://open.nuonuo.com/#/dev-doc/auth-business
-     */
-    public void getMerchantToken() {
-    	// 参数配置
-    	String appKey = "SD47646161";
-    	String appSecret = "SD681C05C3EA4408";
-    	// 接口调用
-    	NNOpenSDK sdk = NNOpenSDK.getIntance();
-    	String json = sdk.getMerchantToken(appKey, appSecret);
-    	
-    	// 响应报文解析
-    	System.out.println("\n\n\n【商户获取Token】");
-    	System.out.println(json);
-    }
-    
-    
-    /**
-     * ISV获取授权码
-     * 
-     * 辅助页面 https://open.nuonuo.com/#/dev-doc/auth-service
-     */
-    public void getISVToken() {
-    	// 参数配置
-    	String appKey = "填写应用的appKey";
-    	String appSecret = "填写应用的appSecret";
-    	String code = "临时授权码,请求authorize时返回的code";
-    	String taxnum = "授权企业的税号,获取临时授权码返回的taxnum";
-    	String redirect_uri = "回调地址,必传且不能为空";
-    	
-    	// 接口调用
-    	NNOpenSDK sdk = NNOpenSDK.getIntance();
-    	String json = sdk.getISVToken(appKey, appSecret, code, taxnum, redirect_uri);
-        
-    	// 响应报文解析
-    	System.out.println("\n\n\n【ISV获取Token】");
-    	System.out.println(json);
-    }
-    
-    /**
-     * ISV刷新授权码
-     * 
-     * 辅助页面 https://open.nuonuo.com/#/dev-doc/auth-service
-     */
-    public void refreshISVToken() {
-    	// 参数配置
-    	String refreshToken = "刷新令牌,由接口getISVToken返回";
-    	String userId = "获取access_token时授权商户的userId";
-    	String appSecret = "填写应用的appSecret";
-    	
-    	// 接口调用
-    	NNOpenSDK sdk = NNOpenSDK.getIntance();
-    	String json = sdk.refreshISVToken(refreshToken, userId, appSecret);
-        
-    	// 响应报文解析
-    	System.out.println("\n\n\n【ISV刷新Token】");
-    	System.out.println(json);
-    }
-}

+ 3 - 3
src/main/resources/application-dev.yml

@@ -2,9 +2,9 @@ spring:
     datasource:
         type: com.alibaba.druid.pool.DruidDataSource
         driverClassName: oracle.jdbc.OracleDriver
-        username: YITOA_DATACENTER
+        username: JYX_ZS
         password: select!#%*(
-        url: jdbc:oracle:thin:@10.10.10.103:1521:orcl
+        url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
         initialSize: 1
         maxActive: 3
         maxWait: 30000
@@ -22,7 +22,7 @@ server:
     tomcat:
         uri_encoding: UTF-8
     context-path:
-        /eis_catl
+        /eis_sf
     port: 8186
 
 action:

+ 3 - 3
src/main/resources/application-prod.yml

@@ -2,9 +2,9 @@ spring:
     datasource:
         type: com.alibaba.druid.pool.DruidDataSource
         driverClassName: oracle.jdbc.OracleDriver
-        username: YITOA_DATACENTER
+        username: JYX_ZS
         password: select!#%*(
-        url: jdbc:oracle:thin:@10.10.10.103:1521:orcl
+        url: jdbc:oracle:thin:@127.0.0.1:1521:orcl
         initialSize: 1
         maxActive: 3
         maxWait: 30000
@@ -22,7 +22,7 @@ server:
     tomcat:
         uri_encoding: UTF-8
     context-path:
-        /eis_catl
+        /eis_sf
     port: 8186
 
 action:

+ 114 - 97
src/test/java/com/uas/eis/UasEisApplicationTests.java

@@ -2,21 +2,20 @@ package com.uas.eis;
 
 
 import com.uas.eis.dao.*;
+import com.uas.eis.entity.sf.*;
 import com.uas.eis.service.ERPService;
 import com.uas.eis.utils.*;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
-import org.apache.http.protocol.HTTP;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.http.HttpStatus;
 import org.springframework.test.context.junit4.SpringRunner;
+import com.sf.csim.express.service.CallExpressServiceTools;
+import com.sf.csim.express.service.HttpClientUtil;
+import com.sf.csim.express.service.IServiceCodeStandard;
+import com.sf.csim.express.service.code.ExpressServiceCodeEnum;
 
+import java.io.UnsupportedEncodingException;
 import java.util.*;
 
 @RunWith(SpringRunner.class)
@@ -26,106 +25,124 @@ public class UasEisApplicationTests {
 	private BaseDao baseDao;
 	@Autowired
 	private ERPService erpService;
+	/**
+	 丰桥新沙箱测试顾客编码  Yg4Zf06w_sxZs3A5D
+	 校验码  3Xdk1jqeG1Xod9nUXus8Op7DNOkchTnw
+	 **/
+	private static final String CLIENT_CODE = "JYXKJWFFJ88E";  //此处替换为您在丰桥平台获取的顾客编码
+	//此处替换为您在丰桥平台获取的校验码
+	private static final String CHECK_WORD_PROD = "GgO0UoyQ5FssNLItii3olo63bQ80ErAE"; //生产校验码
+	private static final String CHECK_WORD_BOX ="rMBhSYRa9OtUPkfX5mow01NlxDWtI411";//沙箱校验码
 
+	//沙箱环境的地址 -PRO
+	private static final String CALL_URL_BOX = "https://sfapi-sbox.sf-express.com/std/service";
+	//生产环境的地址 -PRO
+	private static final String CALL_URL_PROD = "https://sfapi.sf-express.com/std/service";
 	@Test
-	public void TestUrl11(){
-		try {
-			CloseableHttpClient httpClient = HttpClients.createDefault();
-			HttpPost post = new HttpPost("https://ipaassit.catl.com/gateway/outside/ipaas/ipaas/ipaas_getJwtToken");
-			StringEntity postingString =
-					new StringEntity("{\"appKey\":\"WMS_HSL-51J0ISM3\",\"appSecret\":\"52cc3f11-0764-493c-a3bf-a7bcd4f0e66e\",\"time\":\"60\"}"
-							, HTTP.UTF_8);
-			post.setEntity(postingString);
-			// 设置 Authorization 头为 NoAuth
-			post.setHeader("Authorization", "NoAuth");
-			post.setHeader("deipaaskeyauth","n71K0e3D0N783kA04078521ZS28Gh6K5");
-			post.setHeader("Content-type", "application/json");
-			CloseableHttpResponse response = httpClient.execute(post);
-			HttpUtil.Response res = HttpUtil.Response.getResponse(response);
-			System.out.println("response:"+res.getStatusCode());
-			System.out.println("res:"+res.getResponseText());
-		}catch (Exception e){
-			e.printStackTrace();
-		}
-	}
+	public void TestApi() throws UnsupportedEncodingException {
+		/**ExpressServiceCodeEnum     对应速运类-快递APIs
+		 POSTServiceCodeEnum        对应速运类-驿站APIs
+		 YJTServiceCodeEnum         对应解决方案-医寄通APIs
+		 EPSServiceCodeEnum         对应解决方案-快递管家APIs
+		 HZTServiceCodeEnum         对应解决方案-函证通APIs    2022-2-24 新增
+		 详情见code目录下枚举类,客户可自行修改引用的该类
+		 **/
+		IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_ORDER; //下订单
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ORDER_RESP; //查订单
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPDATE_ORDER;//订单取消
+		// 	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_FILTER_ORDER_BSP;//订单筛选
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ROUTES;//查路由
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_GET_SUB_MAILNO;//子单号
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_QUERY_SFWAYBILL;//查运费
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_REGISTER_ROUTE;//注册路由
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CREATE_REVERSE_ORDER;//退货下单
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_CANCEL_REVERSE_ORDER;//退货消单
+		//	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_WANTED_INTERCEPT;//截单转寄
+		// 	IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_QUERY_DELIVERTM;//时效标准及价格查询
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.COM_RECE_CLOUD_PRINT_WAYBILLS;//面单打印
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_UPLOAD_ROUTE;//路由上传
+		//   IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_PROMITM;//预计派送时间查询
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_EXCE_CHECK_PICKUP_TIME;//揽件服务时间查询
+		//  IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_VALIDATE_WAYBILLNO;//运单号合法性校验
 
-	@Test
-	public void TestUrl(){
-		try {
-			HttpUtil.Response response = HttpUtil.doPost("https://ipaassit.catl.com/gateway/outside/ipaas/ipaas/ipaas_getJwtToken"
-					,"{\"appKey\":\"WMS_HSL-51J0ISM3\",\"appSecret\":\"52cc3f11-0764-493c-a3bf-a7bcd4f0e66e\",\"time\":\"60\"}"
-					,"n71K0e3D0N783kA04078521ZS28Gh6K5","");
-			System.out.println("response:"+response.getStatusCode());
-			System.out.println("res:"+response.getResponseText());
-			if (response.getStatusCode() == HttpStatus.OK.value()){
-				String res = response.getResponseText();
-				if(res!=null && !"".equals(res)){
-					System.out.println("res:"+res);
-				}else{
-					System.out.println("???");
-				}
-			}
-		}catch (Exception e){
-			e.printStackTrace();
-		}
-	}
-	/**
-	 * 	获取token
-	 */
-	@Test
-	public void TestToken() {
-		String route = "https://ipaassit.catl.com/gateway/outside/ipaas";
-		String deipaaskeyauth = "n71K0e3D0N783kA04078521ZS28Gh6K5";
-		String action="/ipaas/ipaas_getJwtToken";
-		String appKey = "WMS_HSL-51J0ISM3";
-		String appSecret = "52cc3f11-0764-493c-a3bf-a7bcd4f0e66e";
-		System.out.println("route:"+route+",action:"+action+",deipaaskeyauth:"+deipaaskeyauth+",appKey:"+appKey+",appSecret:"+appSecret);
-		/*
-		* {
-			"appKey":"WMS_HSL-51J0ISM3",
-			"appSecret":"52cc3f11-0764-493c-a3bf-a7bcd4f0e66e",
-			"time":"60"
-		}
-		* */
-		Map<String,Object> paraMap=new HashMap<>();
-		paraMap.put("appKey",appKey);
-		paraMap.put("appSecret",appSecret);
-		paraMap.put("time",60);
-		System.out.println("paraMap:"+ JacksonUtil.toJson(paraMap));
-		try {
-			HttpUtil.Response response =HttpUtil.doPost(route+action, JacksonUtil.toJson(paraMap), deipaaskeyauth,"");
-			if (response.getStatusCode() == HttpStatus.OK.value()){
-				String res = response.getResponseText();
-				if(res!=null && !"".equals(res)){
-					Map<String,Object> resMap = JacksonUtil.fromJson(res);
-					System.out.println(resMap.get("accessToken"));
-				}else{
-					System.out.println("No ResponseText");
+
+		CallExpressServiceTools tools=CallExpressServiceTools.getInstance();
+		Map<String, String> params = new HashMap<String, String>();
+		String timeStamp = String.valueOf(System.currentTimeMillis());
+		String msgData = tools.packageMsgData(standardService);
+		SFCreatOrderReq sfOrder = new SFCreatOrderReq();
+		sfOrder.setOrderId("SD24090018-2");
+		sfOrder.setMonthlyCard("7551234567");
+//		1,寄件方信息 2,到件方信息
+		List<SFContactInfo> contactInfoList = new ArrayList<>();
+		SFContactInfo sendInfo = new SFContactInfo();
+		sendInfo.setContactType(1);
+		sendInfo.setCompany("深圳市佳毅兴科技有限公司");
+		sendInfo.setContact("窦慧怡");
+		sendInfo.setMobile("18128820006");
+		sendInfo.setAddress("广东省深圳市宝安区大宝路51号新柯城业园1栋5楼");
+		contactInfoList.add(sendInfo);
+
+		SFContactInfo receiveInfo = new SFContactInfo();
+		receiveInfo.setContactType(2);
+		receiveInfo.setCompany("深圳市豪锦瑞科技有限公司");
+		receiveInfo.setContact("刘洋");
+		receiveInfo.setMobile("18688770976");
+		receiveInfo.setAddress("深圳市宝安区71区万源商务大厦B栋606");
+		contactInfoList.add(receiveInfo);
+		sfOrder.setContactInfoList(contactInfoList);
+
+		List<SFCargoDetail> cargoDetails = new ArrayList<>();
+		sfOrder.setCargoDetails(cargoDetails);
+		msgData = FlexJsonUtil.toJsonDeep(sfOrder);
+		params.put("partnerID", CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
+		params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
+		params.put("serviceCode",standardService.getCode());// 接口服务码
+		params.put("timestamp", timeStamp);
+		params.put("msgData", msgData);
+		params.put("msgDigest", tools.getMsgDigest(msgData,timeStamp,CHECK_WORD_BOX));
+		long startTime = System.currentTimeMillis();
+
+//		System.out.println("====调用请求:" + params.get("msgData"));
+		System.out.println("====调用实际请求:" + params);
+		String result = HttpClientUtil.post(CALL_URL_BOX, params);
+		System.out.println("====调用丰桥的接口服务代码:" + String.valueOf(standardService.getCode()) + " 接口耗时:"+ String.valueOf(System.currentTimeMillis()-startTime)+"====");
+		System.out.println("===调用地址 ==="+CALL_URL_BOX);
+		System.out.println("===顾客编码 ==="+CLIENT_CODE);
+		System.out.println("===返回结果:" +result);
+//		Map<String,Object> resData = JacksonUtil.fromJson(result);
+		SFApiResp sfApiResp = FlexJsonUtil.fromJson(result, SFApiResp.class);
+		if(sfApiResp!=null){
+			if("A1000".equals(sfApiResp.getApiResultCode())){
+				String apiResultData = sfApiResp.getApiResultData();
+				SFCreatOrderResp sfApiRespData =  FlexJsonUtil.fromJson(apiResultData, SFCreatOrderResp.class);
+				if(sfApiRespData.isSuccess()){
+					SFCreateOrder sfOrderResp =  sfApiRespData.getMsgData();
+					if(!CollectionUtil.isEmpty(sfOrderResp.getWaybillNoInfoList())){
+						for (SFWaybillNoInfo sfWaybillNoInfoResp:sfOrderResp.getWaybillNoInfoList()){
+							System.out.println("顺丰物流单号: ====="+sfWaybillNoInfoResp.getWaybillNo());
+						}
+					}
+				}else {
+					System.out.println("errorCode:"+sfApiRespData.getErrorCode()+"====errorMsg:"+sfApiRespData.getErrorMsg());
 				}
 			}else {
-				System.out.println("response:"+response.getStatusCode());
-				System.out.println("res:"+response.getResponseText());
+				System.out.println("code:"+sfApiResp.getApiResultCode()
+						+"===apiResponseID:"+sfApiResp.getApiResponseID()
+						+"===apiErrorMsg:"+sfApiResp.getApiErrorMsg());
 			}
-		}catch (Exception e){
-			e.printStackTrace();
 		}
 	}
+
 	@Test
-	public void TestGetToken(){
-		Object[] obs = baseDao.getFieldsDataByCondition("YITOA_DATACENTER.dock_catl_config"
-				, new String[]{"URL_","deipaaskeyauth","appKey", "appSecret"}
-				, "username='N_HUASL_SZ' and ENVTYPE = 0 ");
-		Map<String,String> map = new HashMap<>();
-		map.put("url",String.valueOf(obs[0]));
-		map.put("deipaaskeyauth",String.valueOf(obs[1]));
-		map.put("appKey",String.valueOf(obs[2]));
-		map.put("appSecret",String.valueOf(obs[3]));
-		erpService.getToken(map);
+	public void TestCreatSFOrder(){
+		Map<String, Object> res = erpService.creatSFOrder("JYX_TEST", 50734826,"ADMIN");
+		System.out.println("res==="+res.get("success")+":"+res.get("message"));
 	}
+
 	@Test
-	public void TestCreateSticker(){
-		Map<String, Object> resMap = erpService.createSticker2("N_HUASL_SZ", 125);
-		System.out.println("resMap:"+resMap.toString());
+	public void TestCancelSFOrder(){
+		Map<String, Object> res = erpService.cancelSFOrder("JYX_TEST", 50734826,"ADMIN");
+		System.out.println("res==="+res.get("success")+":"+res.get("message"));
 	}
-
 }