Pārlūkot izejas kodu

江阴综服平台订单报关接口对接
1. 海关推送记录建立,记录每次推送的请求响应信息
2. 新增推送校验
TODO: 下单时订单变更为已支付状态,预计2022-10-01之前完成

郑杰 3 gadi atpakaļ
vecāks
revīzija
2b51fbc1e3

+ 161 - 0
framework/src/main/java/cn/lili/common/enums/JGS20Unit.java

@@ -0,0 +1,161 @@
1
+package cn.lili.common.enums;
2
+
3
+import cn.lili.common.exception.UnitIllegalException;
4
+
5
+import java.util.stream.Stream;
6
+
7
+/**
8
+ * JGS-20海关业务代码集 - 计量单位代码
9
+ * @ref http://www.servicetree.cn/?p=456
10
+ */
11
+public enum JGS20Unit {
12
+    UNIT001("台", "001"),
13
+    UNIT002("座", "002"),
14
+    UNIT003("辆", "003"),
15
+    UNIT004("艘", "004"),
16
+    UNIT005("架", "005"),
17
+    UNIT006("套", "006"),
18
+    UNIT007("个", "007"),
19
+    UNIT008("只", "008"),
20
+    UNIT009("头", "009"),
21
+    UNIT010("张", "010"),
22
+    UNIT011("件", "011"),
23
+    UNIT012("支", "012"),
24
+    UNIT013("枝", "013"),
25
+    UNIT014("根", "014"),
26
+    UNIT015("条", "015"),
27
+    UNIT016("把", "016"),
28
+    UNIT017("块", "017"),
29
+    UNIT018("卷", "018"),
30
+    UNIT019("副", "019"),
31
+    UNIT020("片", "020"),
32
+    UNIT021("组", "021"),
33
+    UNIT022("份", "022"),
34
+    UNIT023("幅", "023"),
35
+    UNIT025("双", "025"),
36
+    UNIT026("对", "026"),
37
+    UNIT027("棵", "027"),
38
+    UNIT028("株", "028"),
39
+    UNIT029("井", "029"),
40
+    UNIT030("米", "030"),
41
+    UNIT031("盘", "031"),
42
+    UNIT032("平方米", "032"),
43
+    UNIT033("立方米", "033"),
44
+    UNIT034("筒", "034"),
45
+    UNIT035("千克", "035"),
46
+    UNIT036("克", "036"),
47
+    UNIT037("盆", "037"),
48
+    UNIT038("万个", "038"),
49
+    UNIT039("具", "039"),
50
+    UNIT040("百副", "040"),
51
+    UNIT041("百支", "041"),
52
+    UNIT042("百把", "042"),
53
+    UNIT043("百个", "043"),
54
+    UNIT044("百片", "044"),
55
+    UNIT045("刀", "045"),
56
+    UNIT046("疋", "046"),
57
+    UNIT047("公担", "047"),
58
+    UNIT048("扇", "048"),
59
+    UNIT049("百枝", "049"),
60
+    UNIT050("千只", "050"),
61
+    UNIT051("千块", "051"),
62
+    UNIT052("千盒", "052"),
63
+    UNIT053("千枝", "053"),
64
+    UNIT054("千个", "054"),
65
+    UNIT055("亿支", "055"),
66
+    UNIT056("亿个", "056"),
67
+    UNIT057("万套", "057"),
68
+    UNIT058("千张", "058"),
69
+    UNIT059("万张", "059"),
70
+    UNIT060("千伏安", "060"),
71
+    UNIT061("千瓦", "061"),
72
+    UNIT062("千瓦时", "062"),
73
+    UNIT063("千升", "063"),
74
+    UNIT067("英尺", "067"),
75
+    UNIT070("吨", "070"),
76
+    UNIT071("长吨", "071"),
77
+    UNIT072("短吨", "072"),
78
+    UNIT073("司马担", "073"),
79
+    UNIT074("司马斤", "074"),
80
+    UNIT075("斤", "075"),
81
+    UNIT076("磅", "076"),
82
+    UNIT077("担", "077"),
83
+    UNIT078("英担", "078"),
84
+    UNIT079("短担", "079"),
85
+    UNIT080("两", "080"),
86
+    UNIT081("市担", "081"),
87
+    UNIT083("盎司", "083"),
88
+    UNIT084("克拉", "084"),
89
+    UNIT085("市尺", "085"),
90
+    UNIT086("码", "086"),
91
+    UNIT088("英寸", "088"),
92
+    UNIT089("寸", "089"),
93
+    UNIT095("升", "095"),
94
+    UNIT096("毫升", "096"),
95
+    UNIT097("英加仑", "097"),
96
+    UNIT098("美加仑", "098"),
97
+    UNIT099("立方英尺", "099"),
98
+    UNIT101("立方尺", "101"),
99
+    UNIT110("平方码", "110"),
100
+    UNIT111("平方英尺", "111"),
101
+    UNIT112("平方尺", "112"),
102
+    UNIT115("英制马力", "115"),
103
+    UNIT116("公制马力", "116"),
104
+    UNIT118("令", "118"),
105
+    UNIT120("箱", "120"),
106
+    UNIT121("批", "121"),
107
+    UNIT122("罐", "122"),
108
+    UNIT123("桶", "123"),
109
+    UNIT124("扎", "124"),
110
+    UNIT125("包", "125"),
111
+    UNIT126("箩", "126"),
112
+    UNIT127("打", "127"),
113
+    UNIT128("筐", "128"),
114
+    UNIT129("罗", "129"),
115
+    UNIT130("匹", "130"),
116
+    UNIT131("册", "131"),
117
+    UNIT132("本", "132"),
118
+    UNIT133("发", "133"),
119
+    UNIT134("枚", "134"),
120
+    UNIT135("捆", "135"),
121
+    UNIT136("袋", "136"),
122
+    UNIT139("粒", "139"),
123
+    UNIT140("盒", "140"),
124
+    UNIT141("合", "141"),
125
+    UNIT142("瓶", "142"),
126
+    UNIT143("千支", "143"),
127
+    UNIT144("万双", "144"),
128
+    UNIT145("万粒", "145"),
129
+    UNIT146("千粒", "146"),
130
+    UNIT147("千米", "147"),
131
+    UNIT148("千英尺", "148"),
132
+    UNIT149("百万贝可", "149"),
133
+    UNIT163("部", "163"),
134
+    UNIT164("亿株", "164");
135
+
136
+    JGS20Unit(String cnName, String code) {
137
+        this.cnName = cnName;
138
+        this.code = code;
139
+    }
140
+
141
+    /**
142
+     * 根据中文名称获取
143
+     * @param cnName 中文名称
144
+     * @return JGS-20 标准单位
145
+     */
146
+    public static JGS20Unit ofCnName(String cnName){
147
+        return Stream.of(values())
148
+                .filter(unit -> unit.cnName.equals(cnName))
149
+                .findFirst()
150
+                .orElseThrow(UnitIllegalException::new);
151
+    }
152
+
153
+    /**
154
+     * 中文名称
155
+     */
156
+    public String cnName;
157
+    /**
158
+     * 计量单位代码
159
+     */
160
+    public String code;
161
+}

+ 1 - 0
framework/src/main/java/cn/lili/common/enums/ResultCode.java

@@ -181,6 +181,7 @@ public enum ResultCode {
181 181
     ORDER_BATCH_DELIVER_ERROR(31013, "批量发货,文件读取失败"),
182 182
     ORDER_ITEM_NOT_EXIST(31014, "当前订单项不存在!"),
183 183
     POINT_NOT_ENOUGH(31015, "当前会员积分不足购买当前积分商品!"),
184
+    ORDER_CUSTOMS_ERROR(31016, "订单推送海关失败"),
184 185
 
185 186
 
186 187
     /**

+ 12 - 0
framework/src/main/java/cn/lili/common/exception/UnitIllegalException.java

@@ -0,0 +1,12 @@
1
+package cn.lili.common.exception;
2
+
3
+import lombok.Data;
4
+
5
+@Data
6
+public class UnitIllegalException extends RuntimeException {
7
+
8
+    /**
9
+     * 异常消息
10
+     */
11
+    private String msg = "单位转换失败,请检查单位信息维护是否遵照JGS-20标准,参考网址:http://www.servicetree.cn/?p=456";
12
+}

+ 39 - 8
framework/src/main/java/cn/lili/modules/order/customs/JiangyinServiceManager.java

@@ -1,16 +1,28 @@
1 1
 package cn.lili.modules.order.customs;
2 2
 
3
+import cn.hutool.core.bean.BeanUtil;
3 4
 import cn.hutool.core.date.DatePattern;
4 5
 import cn.hutool.core.date.DateUtil;
6
+import cn.hutool.core.lang.Assert;
5 7
 import cn.hutool.http.HttpUtil;
6 8
 import cn.hutool.json.JSONUtil;
9
+import cn.lili.common.exception.ServiceException;
7 10
 import cn.lili.modules.order.customs.converter.CustomsReqConverter;
11
+import cn.lili.modules.order.order.entity.dos.Order;
12
+import cn.lili.modules.order.order.entity.dos.OrderCustoms;
8 13
 import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
14
+import cn.lili.modules.order.order.mapper.OrderCustomsMapper;
15
+import cn.lili.modules.order.order.mapper.OrderMapper;
16
+import com.dcits.app.encrypt.AESEncrypt;
9 17
 import lombok.extern.slf4j.Slf4j;
10 18
 import org.springframework.beans.factory.annotation.Autowired;
11 19
 import org.springframework.stereotype.Component;
12 20
 
13 21
 import java.time.LocalDateTime;
22
+import java.util.Map;
23
+import java.util.UUID;
24
+
25
+import static cn.lili.common.enums.ResultCode.ORDER_CUSTOMS_ERROR;
14 26
 
15 27
 @Slf4j
16 28
 @Component
@@ -20,30 +32,49 @@ public class JiangyinServiceManager {
20 32
 
21 33
     private final CustomsReqConverter converter;
22 34
 
35
+    private final OrderMapper orderMapper;
36
+
37
+    private final OrderCustomsMapper orderCustomsMapper;
38
+
23 39
     @Autowired
24
-    public JiangyinServiceManager(CustomsReqConverter converter) {
40
+    public JiangyinServiceManager(CustomsReqConverter converter, OrderMapper orderMapper, OrderCustomsMapper orderCustomsMapper) {
25 41
         this.converter = converter;
42
+        this.orderMapper = orderMapper;
43
+        this.orderCustomsMapper = orderCustomsMapper;
26 44
     }
27 45
 
28 46
     public void push(OrderDetailVO detailVO){
47
+        Assert.isTrue(!detailVO.getOrder().getCustomsFlag(), () -> new ServiceException(ORDER_CUSTOMS_ERROR,"订单已推送海关,请勿重复推送"));
29 48
         // 企业凭证相关(后续动态获取)
30 49
         CustomPayload payload = CustomPayload.JiangyinXingguang;
50
+        OrderCustoms customsRec = new OrderCustoms();
31 51
         log.info("method input param: {}, payload: {}", JSONUtil.toJsonStr(detailVO), payload.toString());
32
-        // 报文内容
33
-        String content = converter.toReq(detailVO, payload);
52
+        // 报文内容(密文)
53
+        CustomsExchange exchange = new CustomsExchange(UUID.randomUUID().toString(), detailVO);
54
+        customsRec.setReqMsg(converter.toReq(exchange, payload));
55
+        String encryptContent = AESEncrypt.encrypt(customsRec.getReqMsg(), payload.signKey);
34 56
         // 构建参数
35 57
         JiangyinServiceParam param = JiangyinServiceParam.builder()
36
-                .signMsg(converter.getSign(content, payload.signKey))
37
-                .content(content)
58
+                .signMsg(converter.getSign(encryptContent, payload.signKey))
59
+                .content(encryptContent)
38 60
                 // 唯一序号
39 61
                 .copMsgId(detailVO.getOrder().getSn() + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN))
40 62
                 .sendCode(payload.copCode)
41 63
                 .build();
42 64
         // 开始调用
43
-        String bodyStr = JSONUtil.toJsonStr(param);
44
-        log.info("request body: {}", bodyStr);
45
-        String res = HttpUtil.post(JIANGYIN_ORDER_PUSH_URL, bodyStr, 30000);
65
+        Map<String, Object> paramMap = BeanUtil.beanToMap(param);
66
+        log.info("request body: {}", paramMap);
67
+        String res = HttpUtil.post(JIANGYIN_ORDER_PUSH_URL, paramMap, 30000);
46 68
         log.info("response msg: {}", res);
69
+        customsRec.setResMsg(res);
70
+        if (converter.checkSuccess(res)){
71
+            // 推送成功更新订单状态为已推送
72
+            Order order = exchange.getOrderDetailVO().getOrder();
73
+            order.setCustomsFlag(true);
74
+            order.setCustomsGuid(exchange.getGuid());
75
+            orderMapper.updateById(order);
76
+        }
77
+        orderCustomsMapper.insert(customsRec);
47 78
     }
48 79
 }
49 80
 

+ 5 - 2
framework/src/main/java/cn/lili/modules/order/customs/converter/CustomsReqConverter.java

@@ -1,12 +1,15 @@
1 1
 package cn.lili.modules.order.customs.converter;
2 2
 
3 3
 import cn.lili.modules.order.customs.CustomPayload;
4
-import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
4
+import cn.lili.modules.order.customs.CustomsExchange;
5 5
 
6 6
 public interface CustomsReqConverter{
7 7
     /** 生成报文 */
8
-    String toReq(OrderDetailVO order, CustomPayload payload);
8
+    String toReq(CustomsExchange exchange, CustomPayload payload);
9 9
 
10 10
     /** 获取签名 */
11 11
     String getSign(String content, String key);
12
+
13
+    /** 确认响应信息是否成功调用 */
14
+    boolean checkSuccess(String resStr);
12 15
 }

+ 90 - 86
framework/src/main/java/cn/lili/modules/order/customs/converter/JiangyinServiceReqConverter.java

@@ -4,13 +4,15 @@ import cn.hutool.core.date.DatePattern;
4 4
 import cn.hutool.core.date.DateUtil;
5 5
 import cn.hutool.core.util.XmlUtil;
6 6
 import cn.hutool.crypto.digest.DigestUtil;
7
+import cn.lili.common.enums.JGS20Unit;
8
+import cn.lili.common.exception.ServiceException;
9
+import cn.lili.common.exception.UnitIllegalException;
7 10
 import cn.lili.modules.goods.entity.dos.Goods;
8 11
 import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
9 12
 import cn.lili.modules.goods.service.GoodsService;
10 13
 import cn.lili.modules.order.customs.CustomPayload;
11 14
 import cn.lili.modules.order.customs.CustomsExchange;
12 15
 import cn.lili.modules.order.order.entity.dos.OrderItem;
13
-import cn.lili.modules.order.order.entity.vo.OrderDetailVO;
14 16
 import org.springframework.beans.factory.annotation.Autowired;
15 17
 import org.springframework.stereotype.Component;
16 18
 import org.w3c.dom.Document;
@@ -20,12 +22,12 @@ import java.time.LocalDateTime;
20 22
 import java.util.*;
21 23
 import java.util.stream.Collectors;
22 24
 
25
+import static cn.lili.common.enums.ResultCode.ORDER_CUSTOMS_ERROR;
26
+
23 27
 @Component
24 28
 public class JiangyinServiceReqConverter implements CustomsReqConverter{
25 29
     /** 报文前缀 */
26 30
     private static final String CEB_PREFIX = "ceb:";
27
-    private static final String DS_PREFIX = "ds:";
28
-
29 31
 
30 32
     private final GoodsService goodsService;
31 33
 
@@ -35,22 +37,16 @@ public class JiangyinServiceReqConverter implements CustomsReqConverter{
35 37
     }
36 38
 
37 39
     @Override
38
-    public String toReq(OrderDetailVO order, CustomPayload payload) {
39
-        final String guid = UUID.randomUUID().toString();
40
-        System.out.println(guid);;
41
-        CustomsExchange exchange = new CustomsExchange(guid, order);
40
+    public String toReq(CustomsExchange exchange, CustomPayload payload) {
42 41
         // map解析
43
-        Map<String, Object> m = orderToMap(order, payload);
42
+        Map<String, Object> m = orderToMap(exchange, payload);
44 43
         Document ceb = XmlUtil.mapToXml(m, "ceb:CEB303Message");
45 44
         // 添加首个Node的属性
46 45
         Element element = ceb.getDocumentElement();
47
-        element.setAttribute("guid", "311af125-6fed-4603-8c5d-49b1fa4b4b9b");
46
+        element.setAttribute("guid", exchange.getGuid());
48 47
         element.setAttribute("version", "1.0");
49 48
         element.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
50 49
         element.setAttribute("xmlns:ceb", "http://www.chinaport.gov.cn/ceb");
51
-        //
52
-        Element signature = (Element)element.getLastChild();
53
-        signature.setAttribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");
54 50
         ceb.setXmlStandalone(true);
55 51
         // 转String
56 52
         return XmlUtil.toStr(ceb);
@@ -66,23 +62,28 @@ public class JiangyinServiceReqConverter implements CustomsReqConverter{
66 62
         throw new RuntimeException("gen sign failed.");
67 63
     }
68 64
 
65
+    @Override
66
+    public boolean checkSuccess(String resStr) {
67
+        Map<String, Object> map = XmlUtil.xmlToMap(resStr);
68
+        return Optional
69
+                .ofNullable(map.get("success"))
70
+                .map(String::valueOf)
71
+                .filter("true"::equalsIgnoreCase)
72
+                .isPresent();
73
+    }
74
+
69 75
     /**
70 76
      * 根据订单详情生成符合报文格式的Map
71
-     * @param order 订单详情
77
+     * @param exchange 交换数据(业务)
72 78
      * @param payload 存根(企业凭证相关)
73 79
      * @return 符合报文格式的Map
74 80
      */
75
-    private Map<String, Object> orderToMap(OrderDetailVO order, CustomPayload payload){
76
-        final String guid = UUID.randomUUID().toString();
77
-        System.out.println(guid);;
78
-        CustomsExchange exchange = new CustomsExchange(guid, order);
79
-
81
+    private Map<String, Object> orderToMap(CustomsExchange exchange, CustomPayload payload){
80 82
         Map<String, Object> reqMap = new HashMap<>();
81 83
         // 1. ceb:order
82 84
         reqMap.put(CEB_PREFIX + "Order", order(exchange, payload));
83 85
         // 2. ceb:baseTransfer
84 86
         reqMap.put(CEB_PREFIX + "BaseTransfer", baseTransfer(payload));
85
-
86 87
         return reqMap;
87 88
     }
88 89
 
@@ -98,76 +99,80 @@ public class JiangyinServiceReqConverter implements CustomsReqConverter{
98 99
         List<Map<String, Object>> orderList = new ArrayList<>(0);
99 100
         Optional.ofNullable(exchange.getOrderDetailVO().getOrderItems()).ifPresent(items -> {
100 101
             // 批量获取商品信息
101
-            String ids = items.stream().map(OrderItem::getGoodsId).collect(Collectors.joining());
102
+            String ids = items.stream().map(OrderItem::getGoodsId).collect(Collectors.joining(","));
102 103
             GoodsSearchParams params = new GoodsSearchParams();
103 104
             params.setId(ids);
104 105
             Map<String, String> id2Unit = goodsService.queryListByParams(params).stream()
105 106
                     .collect(Collectors.toMap(Goods::getId, Goods::getGoodsUnit));
106
-            for (int i = 0; i < items.size(); i++) {
107
-                OrderItem item = items.get(i);
108
-                Map<String, Object> itemMap = new HashMap<>();
109
-                Map<String, Object> orderHead = new HashMap<>(32);
110
-                // 1. 表头
111
-                // 电商平台名称
112
-                orderHead.put(CEB_PREFIX + "ebpName", "速贸云");
113
-                // 电商平台代码
114
-                orderHead.put(CEB_PREFIX + "ebpCode", "无");
115
-                // 电商企业名称
116
-                orderHead.put(CEB_PREFIX + "ebcName", payload.copName);
117
-                // 电商企业代码 (电商企业的海关注册登记编号)
118
-                orderHead.put(CEB_PREFIX + "ebcCode", payload.copCode);
119
-                // 系统唯一序号
120
-                orderHead.put(CEB_PREFIX + "guid", exchange.getGuid());
121
-                // 业务状态 (1 - 暂存, 2 - 报送)默认为2
122
-                orderHead.put(CEB_PREFIX + "appStatus", "2");
123
-                // 商品价格 (商品实际价格,含非现金抵扣金额)
124
-                orderHead.put(CEB_PREFIX + "goodsValue", String.valueOf(item.getFlowPrice()));
125
-                // 企业报送类型 (1 - 新增, 2 - 变更, 3 - 删除)默认为1
126
-                orderHead.put(CEB_PREFIX + "appType", "2");
127
-                // 运杂费(不包含在商品价格中的运杂费,无则填写0)
128
-                orderHead.put(CEB_PREFIX + "freight", "0");
129
-                // 订单类型 (I - 进口, E - 9610出口, B - 9710出口, W - 9810出口)
130
-                orderHead.put(CEB_PREFIX + "orderType", "B");
131
-                // 订单编号 (交易平台订单编号,长度不能超过60位)
132
-                orderHead.put(CEB_PREFIX + "orderNo", exchange.getOrderDetailVO().getOrder().getSn());
133
-                // 企业报送时间(格式YYYYMMDDhhmmss)
134
-                orderHead.put(CEB_PREFIX + "appTime", timeStr);
135
-                // 币制 (限定为人民币 - 142)
136
-                orderHead.put(CEB_PREFIX + "currency", "142");
137
-                // 备注
138
-                orderHead.put(CEB_PREFIX + "note", "");
139
-
140
-                Map<String, Object> orderLists = new HashMap<>(32);
141
-                // 2. 表体
142
-                // 商品序号(从1开始递增序号)
143
-                orderLists.put(CEB_PREFIX + "gnum", i + 1);
144
-                // 企业商品货号(SKU编号,最长30位)
145
-                orderLists.put(CEB_PREFIX + "itemNo", item.getSkuId());
146
-                // 企业商品名称(中文名称)
147
-                orderLists.put(CEB_PREFIX + "itemName", item.getGoodsName());
148
-                // 企业商品描述
149
-                orderLists.put(CEB_PREFIX + "itemDescribe", item.getGoodsName());
150
-                // 商品条形码 (非必填)
151
-                orderLists.put(CEB_PREFIX + "barCode", "");
152
-                // 单位
153
-                // TODO 单位映射 必填
154
-                orderLists.put(CEB_PREFIX + "unit", id2Unit.get(item.getGoodsId()));
155
-                // 币制 (限定为人民币 - 142)
156
-                orderLists.put(CEB_PREFIX + "currency", "142");
157
-                // 数量
158
-                orderLists.put(CEB_PREFIX + "qty", item.getNum());
159
-                // 单价
160
-                orderLists.put(CEB_PREFIX + "price", item.getGoodsPrice());
161
-                // 商品价格 (商品实际价格,含非现金抵扣金额)
162
-                orderLists.put(CEB_PREFIX + "totalPrice", String.valueOf(item.getFlowPrice()));
163
-                // 备注
164
-                orderLists.put(CEB_PREFIX + "note", "");
165
-
166
-                // 放入订单列表
167
-                itemMap.put(CEB_PREFIX + "OrderHead", orderHead);
168
-                itemMap.put(CEB_PREFIX + "OrderList", orderLists);
169
-                orderList.add(itemMap);
170
-            }
107
+                for (int i = 0; i < items.size(); i++) {
108
+                    OrderItem item = items.get(i);
109
+                    try {
110
+                        Map<String, Object> itemMap = new HashMap<>();
111
+                        Map<String, Object> orderHead = new HashMap<>(32);
112
+                        // 1. 表头
113
+                        // 电商平台名称
114
+                        orderHead.put(CEB_PREFIX + "ebpName", "速贸云");
115
+                        // 电商平台代码
116
+                        orderHead.put(CEB_PREFIX + "ebpCode", "无");
117
+                        // 电商企业名称
118
+                        orderHead.put(CEB_PREFIX + "ebcName", payload.copName);
119
+                        // 电商企业代码 (电商企业的海关注册登记编号)
120
+                        orderHead.put(CEB_PREFIX + "ebcCode", payload.copCode);
121
+                        // 系统唯一序号
122
+                        orderHead.put(CEB_PREFIX + "guid", exchange.getGuid());
123
+                        // 业务状态 (1 - 暂存, 2 - 报送)默认为2
124
+                        orderHead.put(CEB_PREFIX + "appStatus", "1");
125
+                        // 商品价格 (商品实际价格,含非现金抵扣金额)
126
+                        orderHead.put(CEB_PREFIX + "goodsValue", String.valueOf(item.getFlowPrice()));
127
+                        // 企业报送类型 (1 - 新增, 2 - 变更, 3 - 删除)默认为1
128
+                        orderHead.put(CEB_PREFIX + "appType", "1");
129
+                        // 运杂费(不包含在商品价格中的运杂费,无则填写0)
130
+                        orderHead.put(CEB_PREFIX + "freight", "0");
131
+                        // 订单类型 (I - 进口, E - 9610出口, B - 9710出口, W - 9810出口)
132
+                        orderHead.put(CEB_PREFIX + "orderType", "B");
133
+                        // 订单编号 (交易平台订单编号,长度不能超过60位)
134
+                        orderHead.put(CEB_PREFIX + "orderNo", exchange.getOrderDetailVO().getOrder().getSn());
135
+                        // 企业报送时间(格式YYYYMMDDhhmmss)
136
+                        orderHead.put(CEB_PREFIX + "appTime", timeStr);
137
+                        // 币制 (限定为人民币 - 142)
138
+                        orderHead.put(CEB_PREFIX + "currency", "142");
139
+                        // 备注
140
+                        orderHead.put(CEB_PREFIX + "note", "");
141
+
142
+                        Map<String, Object> orderLists = new HashMap<>(32);
143
+                        // 2. 表体
144
+                        // 商品序号(从1开始递增序号)
145
+                        orderLists.put(CEB_PREFIX + "gnum", i + 1);
146
+                        // 企业商品货号(SKU编号,最长30位)
147
+                        orderLists.put(CEB_PREFIX + "itemNo", item.getSkuId());
148
+                        // 企业商品名称(中文名称)
149
+                        orderLists.put(CEB_PREFIX + "itemName", item.getGoodsName());
150
+                        // 企业商品描述
151
+                        orderLists.put(CEB_PREFIX + "itemDescribe", item.getGoodsName());
152
+                        // 商品条形码 (非必填)
153
+                        orderLists.put(CEB_PREFIX + "barCode", "");
154
+                        // 单位
155
+                        String cnName = id2Unit.get(item.getGoodsId());
156
+                        orderLists.put(CEB_PREFIX + "unit", JGS20Unit.ofCnName(cnName).code);
157
+                        // 币制 (限定为人民币 - 142)
158
+                        orderLists.put(CEB_PREFIX + "currency", "142");
159
+                        // 数量
160
+                        orderLists.put(CEB_PREFIX + "qty", item.getNum());
161
+                        // 单价
162
+                        orderLists.put(CEB_PREFIX + "price", item.getGoodsPrice());
163
+                        // 商品价格 (商品实际价格,含非现金抵扣金额)
164
+                        orderLists.put(CEB_PREFIX + "totalPrice", String.valueOf(item.getFlowPrice()));
165
+                        // 备注
166
+                        orderLists.put(CEB_PREFIX + "note", "");
167
+
168
+                        // 放入订单列表
169
+                        itemMap.put(CEB_PREFIX + "OrderHead", orderHead);
170
+                        itemMap.put(CEB_PREFIX + "OrderList", orderLists);
171
+                        orderList.add(itemMap);
172
+                    } catch (UnitIllegalException e) {
173
+                        throw new ServiceException(ORDER_CUSTOMS_ERROR, String.format("商品[%s]", item.getGoodsName()) + e.getMsg());
174
+                    }
175
+                }
171 176
         });
172 177
 
173 178
         return orderList;
@@ -188,7 +193,6 @@ public class JiangyinServiceReqConverter implements CustomsReqConverter{
188 193
         // 报文传输模式
189 194
         transfer.put(CEB_PREFIX + "dxpMode", "DXP");
190 195
         // 报文传输编号
191
-        // TODO 待平台方确认
192 196
         transfer.put(CEB_PREFIX + "dxpId", payload.dxpId);
193 197
         // 备注
194 198
         transfer.put(CEB_PREFIX + "note", "");

+ 12 - 0
framework/src/main/java/cn/lili/modules/order/order/entity/dos/Order.java

@@ -66,6 +66,18 @@ public class Order extends BaseEntity {
66 66
     private String orderStatus;
67 67
 
68 68
     /**
69
+     * 是否报送海关
70
+     */
71
+    @ApiModelProperty(value = "是否报送海关")
72
+    private Boolean customsFlag;
73
+
74
+    /**
75
+     * 推送海关成功时guid
76
+     */
77
+    @ApiModelProperty(value = "推送海关成功时guid")
78
+    private String customsGuid;
79
+
80
+    /**
69 81
      * @see PayStatusEnum
70 82
      */
71 83
     @ApiModelProperty(value = "付款状态")

+ 59 - 0
framework/src/main/java/cn/lili/modules/order/order/entity/dos/OrderCustoms.java

@@ -0,0 +1,59 @@
1
+package cn.lili.modules.order.order.entity.dos;
2
+
3
+import cn.lili.mybatis.BaseEntity;
4
+import com.baomidou.mybatisplus.annotation.FieldFill;
5
+import com.baomidou.mybatisplus.annotation.TableField;
6
+import com.baomidou.mybatisplus.annotation.TableName;
7
+import com.fasterxml.jackson.annotation.JsonFormat;
8
+import io.swagger.annotations.ApiModel;
9
+import io.swagger.annotations.ApiModelProperty;
10
+import lombok.AllArgsConstructor;
11
+import lombok.Data;
12
+import lombok.EqualsAndHashCode;
13
+import lombok.NoArgsConstructor;
14
+import org.springframework.data.annotation.CreatedBy;
15
+import org.springframework.data.annotation.CreatedDate;
16
+import org.springframework.data.elasticsearch.annotations.DateFormat;
17
+import org.springframework.data.elasticsearch.annotations.Field;
18
+import org.springframework.data.elasticsearch.annotations.FieldType;
19
+import org.springframework.format.annotation.DateTimeFormat;
20
+
21
+import java.util.Date;
22
+
23
+/**
24
+ * 海关报关记录
25
+ *
26
+ * @author Chopper
27
+ * @since 2020/11/17 7:30 下午
28
+ */
29
+@EqualsAndHashCode(callSuper = true)
30
+@Data
31
+@TableName("li_order_customs")
32
+@ApiModel(value = "海关报关记录")
33
+@NoArgsConstructor
34
+@AllArgsConstructor
35
+public class OrderCustoms extends BaseEntity {
36
+
37
+    private static final long serialVersionUID = 2108971190191410183L;
38
+
39
+    @CreatedDate
40
+    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
41
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
42
+    @TableField(fill = FieldFill.INSERT)
43
+    @ApiModelProperty(value = "推送时间")
44
+    @Field(type = FieldType.Date, format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss || yyyy-MM-dd || yyyy/MM/dd HH:mm:ss|| yyyy/MM/dd ||epoch_millis")
45
+    private Date pushTime;
46
+
47
+
48
+    @CreatedBy
49
+    @TableField(fill = FieldFill.UPDATE)
50
+    @ApiModelProperty(value = "推送者")
51
+    private String pushBy;
52
+
53
+    @ApiModelProperty(value = "请求报文")
54
+    private String reqMsg;
55
+
56
+    @ApiModelProperty(value = "响应报文")
57
+    private String resMsg;
58
+
59
+}

+ 15 - 0
framework/src/main/java/cn/lili/modules/order/order/mapper/OrderCustomsMapper.java

@@ -0,0 +1,15 @@
1
+package cn.lili.modules.order.order.mapper;
2
+
3
+import cn.lili.modules.order.order.entity.dos.OrderCustoms;
4
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
5
+
6
+/**
7
+ * 海关报关记录数据处理层
8
+ *
9
+ * @author Chopper
10
+ * @since 2020/11/17 7:34 下午
11
+ */
12
+public interface OrderCustomsMapper extends BaseMapper<OrderCustoms> {
13
+
14
+
15
+}

+ 1 - 0
framework/src/main/java/cn/lili/modules/order/order/serviceimpl/OrderServiceImpl.java

@@ -451,6 +451,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
451 451
 
452 452
     @Override
453 453
     @OrderLogPoint(description = "'订单['+#orderSn+']申请报关'", orderSn = "#orderSn")
454
+    @Transactional(rollbackFor = Exception.class)
454 455
     public void customsPush(String orderSn) {
455 456
         //获取订单信息
456 457
         OrderDetailVO detailVO = this.queryDetail(orderSn);