wuxw7
2017-04-24 980e74ee64ba7e279537e582de46776170d3debd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
package com.java110.order.smo.impl;
 
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.java110.common.constant.ActionTypeConstant;
import com.java110.common.constant.AttrCdConstant;
import com.java110.common.log.LoggerEngine;
import com.java110.common.util.ProtocolUtil;
import com.java110.config.properties.EventProperties;
import com.java110.core.base.smo.BaseServiceSMO;
import com.java110.core.context.AppContext;
import com.java110.core.event.AppEventPublishing;
import com.java110.entity.order.BusiOrder;
import com.java110.entity.order.BusiOrderAttr;
import com.java110.entity.order.OrderList;
import com.java110.entity.order.OrderListAttr;
import com.java110.feign.base.IPrimaryKeyService;
import com.java110.order.dao.IOrderServiceDao;
import com.java110.order.smo.IOrderServiceSMO;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.java110.common.util.Assert;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * 订单服务业务逻辑处理实现类
 * Created by wuxw on 2017/4/11.
 */
@Service("orderServiceSMOImpl")
@Transactional
public class OrderServiceSMOImpl extends BaseServiceSMO implements IOrderServiceSMO {
 
    @Autowired
    IPrimaryKeyService iPrimaryKeyService;
 
    @Autowired
    IOrderServiceDao iOrderServiceDao;
 
    @Autowired
    EventProperties eventProperties;
 
    /**
     * 根据购物车ID 或者 外部系统ID 或者 custId 或者 channelId 查询订单信息
     * @param orderList
     * @return
     */
    @Override
    public String queryOrderInfo(OrderList orderList) throws Exception{
 
 
        List<OrderList> orderLists = iOrderServiceDao.queryOrderListAndAttr(orderList);
        //
        JSONArray orderListsArray = new JSONArray();
        for (OrderList orderListTmp : orderLists){
            //
            BusiOrder busiOrderTmp = new BusiOrder();
            busiOrderTmp.setBoId(orderListTmp.getOlId());
 
            List<BusiOrder> busiOrders = iOrderServiceDao.queryBusiOrderAndAttr(busiOrderTmp);
 
            JSONObject orderListJSON = JSONObject.parseObject(JSONObject.toJSONString(orderListTmp));
 
            orderListJSON.put("busiOrders",JSONObject.parseArray(JSONObject.toJSONString(busiOrders)));
 
            orderListsArray.add(orderListJSON);
        }
 
        JSONObject orderListTmpO = new JSONObject();
        orderListTmpO.put("orderLists",orderListsArray);
 
        return ProtocolUtil.createResultMsg(ProtocolUtil.RETURN_MSG_SUCCESS,"查询成功",orderListTmpO);
    }
 
    /**
     * 订单调度
     *
     * orderListInfo 中字段 asyn 如果为 A 表示 异步处理订单,其他表同步处理订单
     * @param orderInfo 订单信息
     * @return 订单处理接口
     * @throws Exception
     */
    @Override
    public String orderDispatch(JSONObject orderInfo) throws Exception {
 
        //1.0 购物车信息校验处理,走订单受理必须要有购物车信息和订单项信息
        if(!orderInfo.containsKey("orderListInfo") || !orderInfo.containsKey("busiOrder")){
            throw  new IllegalArgumentException("请求报文中没有购物车相关信息[orderListInfo]或订单项相关信息[busiOrder],请检查报文:"+orderInfo);
        }
 
        JSONObject orderListTmp = orderInfo.getJSONObject("orderListInfo");
 
        OrderList orderList = JSONObject.parseObject(orderListTmp.toJSONString(),OrderList.class);
 
        String olId = orderList.getOlId();
        //生成olId
        if(StringUtils.isBlank(olId) || olId.startsWith("-") ){
            olId = this.queryPrimaryKey(iPrimaryKeyService,"OL_ID");
            orderList.setOlId(olId);
        }
 
        //这里保存购物车
 
        int saveOrderListFlag = iOrderServiceDao.saveDataToBoOrderList(orderList);
        if (saveOrderListFlag < 1){
            throw  new RuntimeException("保存购物车信息失败"+orderListTmp);
        }
 
        //保存购物车属性
 
        if(orderInfo.containsKey("orderListAttrs")){
            JSONArray orderListAttrs = orderInfo.getJSONArray("orderListAttrs");
 
            List<OrderListAttr> orderListAttrsTmp = JSONObject.parseArray(orderListAttrs.toJSONString(), OrderListAttr.class);
 
            for(OrderListAttr orderListAttr : orderListAttrsTmp){
                orderListAttr.setOlId(olId);
                saveOrderListFlag = iOrderServiceDao.saveDataToOrderListAttr(orderListAttr);
                if(saveOrderListFlag < 1){
                    throw new RuntimeException("保存购物车属性信息失败"+JSONObject.toJSONString(orderListAttr));
                }
            }
        }
 
 
        //获取 订单项
        JSONArray busiOrderTmps = orderInfo.getJSONArray("busiOrder");
 
        //存放busiOrder 的data节点
 
        Map<String,JSONArray> datasTmp = new HashMap<String, JSONArray>();
 
        for(int busiOrderTmpsIndex = 0 ; busiOrderTmpsIndex < busiOrderTmps.size() ; busiOrderTmpsIndex++){
            JSONObject busiOrderJson = busiOrderTmps.getJSONObject(busiOrderTmpsIndex);
            /*if (!busiOrderJson.containsKey("busiObj")){
                throw new IllegalArgumentException("请求报文中busiOrder 节点中没有对应的 busiObj 节点,请检查"+busiOrderJson);
            }*/
 
            Assert.isNull(busiOrderJson,"busiObj","请求报文中busiOrder 节点中没有对应的 busiObj 节点,请检查"+busiOrderJson);
 
            BusiOrder busiOrderObj = JSONObject.parseObject(busiOrderJson.getJSONObject("busiObj").toJSONString(),BusiOrder.class);
 
            String boId = busiOrderObj.getBoId();
            //生成 订单项ID
            if(StringUtils.isBlank(boId) || boId.startsWith("-")){
                boId = this.queryPrimaryKey(iPrimaryKeyService,"BO_ID");
            }
            busiOrderObj.setOlId(olId);
            //修改boId
            busiOrderObj.setBoId(boId);
 
            //这里保存订单项 busiOrder
            int saveBusiOrderFlag = iOrderServiceDao.saveDataToBusiOrder(busiOrderObj);
            if(saveBusiOrderFlag < 1){
                throw new RuntimeException("保存订单项信息失败"+JSONObject.toJSONString(busiOrderObj));
            }
 
            //如果有busiOrderAttrs 节点 每个节点添加 boId
            if(busiOrderJson.containsKey("busiOrderAttrs")){
                List<BusiOrderAttr> busiOrderAttrsTmp = JSONObject.parseArray(busiOrderJson.getJSONArray("busiOrderAttrs").toJSONString(),
                        BusiOrderAttr.class);
 
                for (BusiOrderAttr busiOrderAttrTmp : busiOrderAttrsTmp){
                    busiOrderAttrTmp.setBoId(boId);
                    //这里保存订单项属性
                    saveBusiOrderFlag =  iOrderServiceDao.saveDataToBusiOrderAttr(busiOrderAttrTmp);
                    if(saveBusiOrderFlag < 1){
                        throw new RuntimeException("保存订单项信息属性失败"+JSONObject.toJSONString(busiOrderAttrTmp));
                    }
                }
            }
            //修改data节点下的boId,一般是没有这个值,所以直接新加就行了,不许判断是否已-开头
           /* if (!busiOrderJson.containsKey("data")){
                throw new IllegalArgumentException("请求报文中busiOrder 节点中没有对应的 data 节点,请检查"+busiOrderJson);
            }*/
 
            Assert.isNull(busiOrderJson,"data","请求报文中busiOrder 节点中没有对应的 data 节点,请检查"+busiOrderJson);
 
            //处理data 节点
            JSONObject data = busiOrderJson.getJSONObject("data");
 
            for (Map.Entry<String, Object> entry : data.entrySet()) {
                Object valueObj = entry.getValue();
                if (valueObj instanceof JSONObject){
                    ((JSONObject)valueObj).put("boId",boId);
                }else if(valueObj instanceof JSONArray){
                    JSONArray valueArray = (JSONArray)valueObj;
                    for(int valueIndex = 0 ; valueIndex < valueArray.size(); valueIndex++){
                        valueArray.getJSONObject(valueIndex).put("boId",boId);
                    }
                }
            }
 
            LoggerEngine.debug("处理后的data节点 :" + data.toString());
 
            //根据busiOrder 的  actionTypeCd 注册那个服务去处理
            String actionTypeCd = busiOrderObj.getActionTypeCd();
 
            JSONArray dataJsonTmp = null;
            if(!datasTmp.containsKey(actionTypeCd)){
                dataJsonTmp = new JSONArray();
            }else{
                dataJsonTmp = datasTmp.get(actionTypeCd);
            }
            data.put("actionTypeCd",actionTypeCd);
            dataJsonTmp.add(data);
 
            datasTmp.put(actionTypeCd,dataJsonTmp);
 
            /*
            try {
                //发布事件
                AppEventPublishing.multicastEvent(actionTypeCd,orderInfo.toJSONString(), data.toJSONString(),orderListTmp.getString("asyn"));
            }catch (Exception e){
                //这里补偿事物
                throw e;
            }*/
 
        }
 
        //创建上下文对象
        AppContext context = createApplicationContext();
 
        prepareContext(context, datasTmp);
        try {
            //发布事件
            AppEventPublishing.multicastEvent(context,datasTmp,orderListTmp.getString("asyn"));
        }catch (Exception e){
            //这里补偿事物
            throw e;
        }
        return ProtocolUtil.createResultMsg(ProtocolUtil.RETURN_MSG_SUCCESS,"成功",JSONObject.parseObject(JSONObject.toJSONString(orderList)));
    }
 
    /**
     * 作废订单
     * 根据业务动作作废
     * 请求协议:
     * {
     *     "orderList":{
     *     "transactionId": "1000000200201704113137002690",
             "channelId": "700212896",
             "remarks": "",
             "custId": "701008023904",
             "statusCd": "S",
             "reqTime": "20170411163709",
             "extSystemId": "310013698777",
             "olTypeCd": "15",
     *        "oldOlId":"123456789",
     *        "asyn":"S"
     *     },
     *     "busiOrder":[{
     *         "actionTypeCd":"ALL"
     *     }]
     * }
     *
     * ,
     *
     * 根据 订单项ID作废
     *
     * {
     *     "orderList":{
     *         "transactionId": "1000000200201704113137002690",
     "channelId": "700212896",
     "remarks": "",
     "custId": "701008023904",
     "statusCd": "S",
     "reqTime": "20170411163709",
     "extSystemId": "310013698777",
     "olTypeCd": "15",
     "asyn":"A"
     *     },
     *     "busiOrder":[{
     *          "oldBoId":"123456789"
     *     },
     *     {
     *          "oldBoId":"123456799"
     *     }]
     * }
     * @param orderInfo
     * @return
     * @throws Exception
     */
    @Override
    public String deleteOrder(JSONObject orderInfo) throws Exception {
        //1.0 购物车信息校验处理,走订单受理必须要有购物车信息和订单项信息
        if(!orderInfo.containsKey("orderList") || !orderInfo.containsKey("busiOrder")){
            throw  new IllegalArgumentException("请求报文中没有购物车相关信息[orderList]或订单项相关信息[busiOrder],请检查报文:"+orderInfo);
        }
 
        JSONObject orderListTmp = orderInfo.getJSONObject("orderList");
        OrderList orderList = JSONObject.parseObject(orderListTmp.toJSONString(),OrderList.class);
 
        String olId = orderList.getOlId();
        //生成olId
        if(StringUtils.isBlank(olId) || olId.startsWith("-") ){
            olId = this.queryPrimaryKey(iPrimaryKeyService,"OL_ID");
            orderList.setOlId(olId);
        }
 
        //这里保存购物车
 
        int saveOrderListFlag = iOrderServiceDao.saveDataToBoOrderList(orderList);
        if (saveOrderListFlag < 1){
            throw  new RuntimeException("作废订单时保存购物车信息失败"+orderListTmp);
        }
 
        JSONArray busiOrderTmps = orderInfo.getJSONArray("busiOrder");
 
        /**
         * 根据actionTypeCd 作废
         */
        Assert.isNull(busiOrderTmps,"入参错误,没有busiOrder 节点,或没有子节点");
 
        List<Map<String,String>> needDeleteBoIds = new ArrayList<Map<String,String>>();
 
        if(busiOrderTmps.getJSONObject(0).containsKey("actionTypeCd")){
           String actionTypeCds = busiOrderTmps.getJSONObject(0).getString("actionTypeCd");
            getNeeddeleteOrderByActionTypeCd(orderListTmp.getString("oldOlId"),needDeleteBoIds,actionTypeCds.split(","));
            //return ProtocolUtil.createResultMsg(ProtocolUtil.RETURN_MSG_SUCCESS,"成功",JSONObject.parseObject(JSONObject.toJSONString(orderList)));
        }else if(busiOrderTmps.getJSONObject(0).containsKey("oldBoId")){
            Map<String,String> oldBoIdMap = null;
            for(int busiOrderIndex = 0; busiOrderIndex< busiOrderTmps.size();busiOrderIndex++){
                oldBoIdMap = new HashMap<String, String>();
                oldBoIdMap.put("actionTypeCd","");
                oldBoIdMap.put("boId",busiOrderTmps.getJSONObject(busiOrderIndex).getString("oldBoId"));
                oldBoIdMap.put("olId","");
                needDeleteBoIds.add(oldBoIdMap);
            }
        }else {
            throw new IllegalArgumentException("当前系统只支持busiOrder 节点下第一个节点包含 actionTypeCd节点和 oldOlId节点的报文:"+orderInfo);
        }
 
        //数据分装
        Map<String,JSONArray> datasTmp = new HashMap<String, JSONArray>();
        //添加数据至 busi_order,这里生成新的boId 将需要作废的boId信息写入值busi_order_attr 中单独注册一个属性信息
 
        for(Map<String,String> needDeleteBoIdMap : needDeleteBoIds){
            BusiOrder busiOrder = new BusiOrder();
 
            String newBoId = this.queryPrimaryKey(iPrimaryKeyService,"BO_ID");
 
            busiOrder.setOlId(olId);
            //重新生成 boId
            busiOrder.setBoId(newBoId);
            //设置撤单,作废订单动作
            busiOrder.setActionTypeCd(ActionTypeConstant.ACTION_TYPE_CANCEL_ORDER);
 
            busiOrder.setRemark("撤单,作废订单处理,作废订单为"+needDeleteBoIdMap.get("boId"));
 
            //这里保存订单项 busiOrder
            int saveBusiOrderFlag = iOrderServiceDao.saveDataToBusiOrder(busiOrder);
            if(saveBusiOrderFlag < 1){
                throw new RuntimeException("撤单,作废订单失败,保存订单项信息失败"+JSONObject.toJSONString(busiOrder));
            }
 
            //将需要作废的订单boId 写入值 busi_order_attr 中 属性为: 10000001
 
            BusiOrderAttr busiOrderAttr = new BusiOrderAttr();
            busiOrderAttr.setBoId(newBoId);
            busiOrderAttr.setAttrCd(AttrCdConstant.BUSI_ORDER_ATTR_10000001);
            busiOrderAttr.setValue(needDeleteBoIdMap.get("boId"));
 
            saveBusiOrderFlag =  iOrderServiceDao.saveDataToBusiOrderAttr(busiOrderAttr);
            if(saveBusiOrderFlag < 1){
                throw new RuntimeException("撤单,作废订单失败,保存订单项信息属性失败"+JSONObject.toJSONString(busiOrderAttr));
            }
 
 
 
        }
 
        //这里补充 order_list_attr中 编码为 10000002 的数据,要作废 订单购物车信息,真正作废单子是以 busi_order_attr 中的boId 为主
 
 
 
 
 
        return null;
    }
 
    /**
     * 根据 订单动作 作废
     * @param oldOlId 作废的购物车
     * @param actionTypeCd busi_order action_type_cd 类型来作废订单
     * @throws Exception
     */
    private void getNeeddeleteOrderByActionTypeCd(String oldOlId,List<Map<String,String>> needDeleteBoIds,String ...actionTypeCd) throws Exception{
        //根据oldOdId actionTypeCd 获取订单项
        BusiOrder busiOrderTmp = new BusiOrder();
        busiOrderTmp.setOlId(oldOlId);
        String actionTypeCds= "";
        // 'C1','A1','M1',
        for(String ac : actionTypeCd){
            actionTypeCds += ("'"+ac+"',");
        }
 
        // 'C1','A1','M1'
        actionTypeCds = actionTypeCds.endsWith(",")?actionTypeCds.substring(0,actionTypeCds.length()-1):actionTypeCds;
 
        //如果为 ALL 作废整个订单数据,这里直接传为空 根据olId 处理
        if("ALL".equals(actionTypeCds)){
 
            actionTypeCds = "";
        }
 
        busiOrderTmp.setActionTypeCd(actionTypeCds);
 
        /**
         * 已经生成的订单项信息
         */
        List<BusiOrder> oldBusiOrders =  iOrderServiceDao.queryBusiOrderAndAttr(busiOrderTmp);
 
        Assert.isNull(oldBusiOrders,"没有找到需要作废的订单,[oldOdId="+oldOlId+",actionTypeCd = "+actionTypeCd+"]");
 
        //作废老订单信息
        Map<String,String> oldBoIdMap = null;
        for(BusiOrder oldBusiOrder : oldBusiOrders){
            oldBoIdMap = new HashMap<String, String>();
            oldBoIdMap.put("actionTypeCd",oldBusiOrder.getActionTypeCd());
            oldBoIdMap.put("boId",oldBusiOrder.getBoId());
            oldBoIdMap.put("olId",oldBusiOrder.getOlId());
            needDeleteBoIds.add(oldBoIdMap);
        }
    }
 
    private void prepareContext(AppContext context,Map<String,JSONArray> datasTmp){
        Assert.isNull(context,"创建上下对象失败");
 
        //这里将整个订单的data 信息存入 上下文对象中,以防后期使用无法获取
 
        context.coverData(datasTmp);
 
    }
 
 
    /**
     *
     * oldBoIdMap.put("actionTypeCd","");
     *
     *  oldBoIdMap.put("boId",busiOrderTmps.getJSONObject(busiOrderIndex).getString("oldBoId"));
     *  oldBoIdMap.put("olId","");
     * @param needDeleteBoIdMap
     *
     */
    private void processDeleteOrderByActionTypeCd(Map<String,String> needDeleteBoIdMap,Map<String,JSONArray> datasTmp){
 
        Assert.isNull(datasTmp,"processDeleteOrderByActionTypeCd 方法的参数 datasTmp 为空,");
 
        // 如果这两个中有一个为空,则从库中查询
        if(StringUtils.isBlank(needDeleteBoIdMap.get("olId")) || StringUtils.isBlank(needDeleteBoIdMap.get("actionTypeCd"))){
            BusiOrder busiOrderTmp = new BusiOrder();
            busiOrderTmp.setBoId(needDeleteBoIdMap.get("boId"));
            //这里只有一条其他,则抛出异常
            List<BusiOrder> oldBusiOrders =  iOrderServiceDao.queryBusiOrderAndAttr(busiOrderTmp);
 
            if(oldBusiOrders == null || oldBusiOrders.size() != 1){
                throw new IllegalArgumentException("当前[boId="+needDeleteBoIdMap.get("boId")+"] 数据在busi_order表中不存在,请处理,很有可能是入参错误");
            }
 
            //回写数据
 
            needDeleteBoIdMap.put("olId",oldBusiOrders.get(0).getOlId());
            needDeleteBoIdMap.put("actionTypeCd",oldBusiOrders.get(0).getActionTypeCd());
        }
 
        String actionTypeCd = needDeleteBoIdMap.get("actionTypeCd");
 
        JSONArray dataJsonTmp = null;
        if(!datasTmp.containsKey(actionTypeCd)){
            dataJsonTmp = new JSONArray();
        }else{
            dataJsonTmp = datasTmp.get(actionTypeCd);
        }
        dataJsonTmp.add(JSONObject.parseObject(JSONObject.toJSONString(needDeleteBoIdMap)));
        datasTmp.put(actionTypeCd,dataJsonTmp);
    }
 
    public IPrimaryKeyService getiPrimaryKeyService() {
        return iPrimaryKeyService;
    }
 
    public void setiPrimaryKeyService(IPrimaryKeyService iPrimaryKeyService) {
        this.iPrimaryKeyService = iPrimaryKeyService;
    }
 
    public IOrderServiceDao getiOrderServiceDao() {
        return iOrderServiceDao;
    }
 
    public void setiOrderServiceDao(IOrderServiceDao iOrderServiceDao) {
        this.iOrderServiceDao = iOrderServiceDao;
    }
 
    public EventProperties getEventProperties() {
        return eventProperties;
    }
 
    public void setEventProperties(EventProperties eventProperties) {
        this.eventProperties = eventProperties;
    }
}