shikeyin
2024-01-11 65da8373531677b1c37a98f53eaa30c892f35e5a
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
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
package com.ishop.mobile.api;
 
import com.iplatform.base.Constants;
import com.iplatform.base.PlatformRuntimeException;
import com.ishop.merchant.OrderConstants;
import com.ishop.merchant.ProductConstants;
import com.ishop.mobile.BaseApi;
import com.ishop.mobile.pojo.PreOrderRequest;
import com.ishop.mobile.util.OrderUtils;
import com.ishop.mobile.util.VoUtils;
import com.ishop.model.MyRecord;
import com.ishop.model.po.EbMerchant;
import com.ishop.model.po.EbMerchantOrder;
import com.ishop.model.po.EbOrder;
import com.ishop.model.po.EbOrderDetail;
import com.ishop.model.po.EbProduct;
import com.ishop.model.po.EbProductAttrValue;
import com.ishop.model.po.EbUser;
import com.ishop.model.po.EbUserAddress;
import com.ishop.model.request.CreateOrderRequest;
import com.ishop.model.request.OrderComputedPriceRequest;
import com.ishop.model.request.OrderMerchantRequest;
import com.ishop.model.response.ComputedMerchantOrderResponse;
import com.ishop.model.response.ComputedOrderPriceResponse;
import com.ishop.model.response.MerchantOrderFrontDetailResponse;
import com.ishop.model.response.OrderFrontDetailResponse;
import com.ishop.model.vo.OrderDetailFrontVo;
import com.ishop.model.vo.OrderFrontVo;
import com.ishop.model.vo.OrderNoVo;
import com.ishop.model.vo.PreMerchantOrderVo;
import com.ishop.model.vo.PreOrderDetailVo;
import com.ishop.model.vo.PreOrderResponse;
import com.ishop.model.vo.PreOrderVo;
import com.walker.db.page.GenericPager;
import com.walker.db.page.ListPageContext;
import com.walker.infrastructure.utils.JsonUtils;
import com.walker.infrastructure.utils.NumberFormatUtils;
import com.walker.infrastructure.utils.NumberGenerator;
import com.walker.infrastructure.utils.StringUtils;
import com.walker.web.ResponseValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
@RestController
@RequestMapping("/front/order")
public class OrderApi extends BaseApi {
 
    /**
     * 获取订单状态图
     * @return
     * @date 2023-07-13
     */
    @RequestMapping(value = "/status/image", method = RequestMethod.GET)
    public ResponseValue getOrderStatusImage(){
        List<HashMap<String, Object>> mapList = this.acquireGroupDataConfigList(Constants.GROUP_DATA_ID_ORDER_STATUS_IMAGE, this.getCdnUrl());
        return ResponseValue.success(mapList);
    }
 
    /**
     * 订单列表:订单详情
     * @param orderNo
     * @return
     * @date 2023-07-13
     */
    @RequestMapping(value = "/detail/{orderNo}", method = RequestMethod.GET)
    public ResponseValue detail(@PathVariable String orderNo){
        if(StringUtils.isEmpty(orderNo)){
            return ResponseValue.error("请选择一个订单");
        }
        EbOrder order = this.getOrderService().queryOrder(orderNo);
        if(order == null){
            return ResponseValue.error("订单不存在");
        }
 
        OrderFrontDetailResponse response = VoUtils.acquireOrderFrontDetailResponse(order);
        List<EbMerchantOrder> merchantOrderList = this.getOrderService().queryMerchantOrderList(orderNo);
        List<EbOrderDetail> orderDetailList = this.getOrderService().queryOrderDetailList(orderNo);
 
        Map<Integer, List<EbOrderDetail>> orderDetailMap = orderDetailList.stream().collect(Collectors.groupingBy(EbOrderDetail::getMerId));
 
        List<MerchantOrderFrontDetailResponse> merDetailResponseList = new ArrayList<>(8);
        MerchantOrderFrontDetailResponse merDetailResponse = null;
        EbMerchant merchant = null;
        for (EbMerchantOrder merchantOrder : merchantOrderList) {
            merDetailResponse = new MerchantOrderFrontDetailResponse();
            merchant = this.getMerchantCache().get(merchantOrder.getMerId());
            merDetailResponse.setMerName(merchant.getName());
            if (merchantOrder.getShippingType().equals(OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP)) {
                merDetailResponse.setMerPhone(merchant.getPhone());
                merDetailResponse.setMerProvince(merchant.getProvince());
                merDetailResponse.setMerCity(merchant.getCity());
                merDetailResponse.setMerDistrict(merchant.getDistrict());
                merDetailResponse.setMerAddressDetail(merchant.getAddressDetail());
                merDetailResponse.setMerLatitude(merchant.getLatitude());
                merDetailResponse.setMerLongitude(merchant.getLongitude());
            }
            List<EbOrderDetail> detailList = orderDetailMap.get(merchantOrder.getMerId());
            List<OrderDetailFrontVo> dataResponseList = new ArrayList<>(2);
            OrderDetailFrontVo detailFrontVo = null;
            for(EbOrderDetail detail : detailList){
                detailFrontVo = com.ishop.merchant.util.VoUtils.acquireOrderDetailFrontVo(detail);
                dataResponseList.add(detailFrontVo);
            }
            merDetailResponse.setOrderInfoList(dataResponseList);
            merDetailResponseList.add(merDetailResponse);
        }
        response.setMerchantOrderList(merDetailResponseList);
        return ResponseValue.success(response);
    }
 
    /**
     * 创建订单
     * @return
     * @date 2023-07-08
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public ResponseValue createOrder(@RequestBody CreateOrderRequest orderRequest){
        if(orderRequest == null || StringUtils.isEmpty(orderRequest.getPreOrderNo())
            || StringUtils.isEmptyList(orderRequest.getOrderMerchantRequestList())){
            return ResponseValue.error("订单请求参数不完整");
        }
        EbUser user = this.getCurrentEbUser();
        PreOrderVo preOrderVo = this.getPreOrderCache().get(orderRequest.getPreOrderNo());
        if(preOrderVo == null){
            return ResponseValue.error("预下单记录不存在,请重新下单");
        }
        if(preOrderVo.getType().intValue() == OrderConstants.ORDER_TYPE_SECKILL){
            // 秒杀订单
            return ResponseValue.success(this.doCreateSecondsKillOrder());
        }
 
        List<OrderMerchantRequest> orderMerchantRequestList = orderRequest.getOrderMerchantRequestList();
        if(StringUtils.isEmptyList(orderMerchantRequestList)){
            throw new PlatformRuntimeException("商品列表不存在");
        }
 
        List<PreMerchantOrderVo> merchantOrderVoList = preOrderVo.getMerchantOrderVoList();
        EbUserAddress userAddress = null;
        boolean autoShippingDone = this.isAutoShippingDone(merchantOrderVoList);
        if(!autoShippingDone){
            // 实物商品,正常发货
            if(orderRequest.getAddressId() == null || orderRequest.getAddressId().longValue() <= 0){
                return ResponseValue.error("请选择收货地址");
            }
            userAddress = this.checkUserAddress(orderMerchantRequestList, orderRequest.getAddressId());
        }
 
        this.checkIsTakeTheir(orderMerchantRequestList);
 
        // 校验商品库存
        List<MyRecord> skuRecordList = this.checkProductStock(preOrderVo.getType(), merchantOrderVoList);
        // 计算订单各种价格
        this.doComputeFreightFee(preOrderVo, userAddress, autoShippingDone);
        this.acquireCouponFee(preOrderVo, orderMerchantRequestList, user.getId());    // getCouponFee()
        if (orderRequest.getIsUseIntegral() && user.getIntegral() > 0) {// 使用积分
            this.doComputeIntegralDeduction(preOrderVo, user.getIntegral());
        }
 
        // 平台订单
        EbOrder order = OrderUtils.acquirePlatformOrder(user.getId(), preOrderVo);
        // 商户订单
        List<Long> couponIdList = new ArrayList<>(4);
        Object[] orderResult = OrderUtils.acquireMerchantOrderList(couponIdList
                , merchantOrderVoList, orderMerchantRequestList, order.getOrderNo(), order.getType(), user.getId()
                , order.getCreateTime(), userAddress, autoShippingDone);
        List<EbMerchantOrder> merchantOrderList = (List<EbMerchantOrder>)orderResult[0];
        List<EbOrderDetail> orderDetailList = (List<EbOrderDetail>)orderResult[1];
        if(logger.isDebugEnabled()){
            try {
                logger.debug("订单生成:商户订单列表: {}", JsonUtils.objectToJsonString(merchantOrderList));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 
        this.getFrontOrderService().execCreateOrder(order.getType(), skuRecordList
                , orderRequest.getPreOrderNo(), order, merchantOrderList, orderDetailList, couponIdList, preOrderVo.getCartIdList());
        this.getPreOrderCache().remove(orderRequest.getPreOrderNo());
        logger.debug("订单创建成功!删除缓存:预订单记录," + orderRequest.getPreOrderNo());
 
        // 加入自动未支付自动取消队列
//        redisUtil.lPush(TaskConstants.ORDER_TASK_REDIS_KEY_AUTO_CANCEL_KEY, order.getOrderNo());
        OrderNoVo response = new OrderNoVo();
        response.setOrderNo(order.getOrderNo());
        response.setPayPrice(order.getPayPrice());
        return ResponseValue.success(response);
    }
 
    /**
     * 检测订单中商品是否(全部)为虚拟商品,如果是则无需发货,订单直接完成。
     * @param merchantOrderVoList
     * @return
     * @date 2023-09-09
     */
    private boolean isAutoShippingDone(List<PreMerchantOrderVo> merchantOrderVoList){
        for(PreMerchantOrderVo merchantOrderVo: merchantOrderVoList){
            EbProduct product = null;
            for(PreOrderDetailVo info: merchantOrderVo.getOrderInfoList()){
                product = this.getProductCache().get(info.getProductId());
                if(product.getTempId().intValue() != com.ishop.merchant.Constants.SHIPPING_TEMPLATE_ID_NO_SEND){
                    return false;
                }
            }
        }
        return true;
    }
 
    /**
     * 计算积分抵扣(创建订单),
     * <p>参考方法:integralDeductionComputed()</p>
     * @param preOrderVo
     * @param userIntegral
     */
    private void doComputeIntegralDeduction(PreOrderVo preOrderVo, int userIntegral){
        boolean integralDeductionEnabled = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_MONEY).getBooleanValue();
        if(preOrderVo.getIsUseIntegral() && !integralDeductionEnabled){
            throw new PlatformRuntimeException("积分抵扣未开启,无法使用积分");
        }
        double payPrice = preOrderVo.getProTotalFee() - preOrderVo.getCouponFee();
        double integralDeductionStartMoney = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_START_MONEY).getDoubleValue();
        if(integralDeductionStartMoney <= 0 || payPrice < integralDeductionStartMoney){
            throw new PlatformRuntimeException("支付金额不满足积分抵扣起始金额,请重新下单");
        }
        // 查询积分使用比例
        logger.warn("创建订单:计算积分抵扣代码未实现");
    }
 
    private List<MyRecord> checkProductStock(int orderType, List<PreMerchantOrderVo> merchantOrderVoList) {
        List<MyRecord> recordList = new ArrayList<>(4);
        if(orderType == OrderConstants.ORDER_TYPE_SECKILL){
            logger.warn("秒杀商品订单,检查库存代码未实现");
            return recordList;
        }
        if(orderType == OrderConstants.ORDER_TYPE_VIDEO){
            // 查询商品信息 视频号都是单品下单
            logger.warn("视频号商品订单,检查库存代码未实现");
            return recordList;
        }
        // 普通商品
        EbMerchant merchant = null;
        for(PreMerchantOrderVo merchantOrderVo: merchantOrderVoList){
            merchant = this.getMerchantCache().get(merchantOrderVo.getMerId());
            if(merchant.getIsSwitch().intValue() == 0){
                throw new PlatformRuntimeException("商户已关闭,请重新下单");
            }
            EbProduct product = null;
            for(PreOrderDetailVo info: merchantOrderVo.getOrderInfoList()){
//                product = this.getProductService().get(new EbProduct(info.getProductId()));
                product = this.getProductCache().get(info.getProductId());
                if(product == null || product.getIsDel().intValue() == 1){
                    throw new PlatformRuntimeException("购买的商品信息不存在");
                }
                if (product.getIsShow().intValue() == 0) {
                    throw new PlatformRuntimeException("购买的商品已下架");
                }
                if (product.getStock().intValue() == 0 || info.getPayNum().intValue() > product.getStock().intValue()) {
                    throw new PlatformRuntimeException("购买的商品库存不足");
                }
                EbProductAttrValue attrValue = this.getProductAttrValueService().queryByIdAndProductIdAndType(info.getAttrValueId(), product.getId(), ProductConstants.PRODUCT_TYPE_NORMAL);
                if (attrValue == null) {
                    throw new PlatformRuntimeException("购买的商品规格信息不存在");
                }
                if (attrValue.getStock().intValue() < info.getPayNum().intValue()) {
                    throw new PlatformRuntimeException("购买的商品库存不足");
                }
                MyRecord record = new MyRecord();
                record.set("productId", info.getProductId());
                record.set("num", info.getPayNum());
                record.set("attrValueId", info.getAttrValueId());
                record.set("attrValueVersion", attrValue.getVersion());
                recordList.add(record);
            }
        }
        return recordList;
    }
 
    private EbUserAddress checkUserAddress(List<OrderMerchantRequest> orderMerchantRequestList, Long addressId){
        EbUserAddress userAddress = null;
        for(OrderMerchantRequest request: orderMerchantRequestList){
            if(request.getShippingType().intValue() == OrderConstants.ORDER_SHIPPING_TYPE_EXPRESS){
                if(addressId == null || addressId.longValue() <= 0){
                    throw new PlatformRuntimeException("请选择收获地址");
                }
                userAddress = this.getUserAddressService().get(new EbUserAddress(addressId));
                if(userAddress == null || userAddress.getIsDel().intValue() == 1){
                    throw new PlatformRuntimeException("收获地址不存在");
                }
            }
        }
        return userAddress;
    }
 
    private OrderNoVo doCreateSecondsKillOrder(){
        logger.warn("秒杀订单,创建代码未实现");
        return new OrderNoVo();
    }
 
    /**
     * 计算订单价格。
     * @return
     */
    @RequestMapping(value = "/computed/price", method = RequestMethod.POST)
    public ResponseValue computedPrice(@RequestBody OrderComputedPriceRequest request){
        String key = request.getPreOrderNo();
        PreOrderVo preOrderVo = this.getPreOrderCache().get(key);
        if(preOrderVo == null){
            return ResponseValue.error("预下单信息不存在");
        }
        List<OrderMerchantRequest> orderMerchantRequestList = request.getOrderMerchantRequestList();
        if(StringUtils.isEmptyList(orderMerchantRequestList)){
            throw new PlatformRuntimeException("商品列表不存在");
        }
//        if(StringUtils.isEmptyList(orderMerchantRequestList)){
//            return ResponseValue.error("商品列表不存在");
//        }
//        for(OrderMerchantRequest orderMerchantRequest : orderMerchantRequestList){
//            if(orderMerchantRequest.getShippingType().intValue() == OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP
//                && this.getMerchantCache().get(orderMerchantRequest.getMerId()).getIsTakeTheir() == 0){
//                return ResponseValue.error("商户未开启门店自提功能");
//            }
//        }
        this.checkIsTakeTheir(orderMerchantRequestList);
        boolean integralDeductionEnabled = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_MONEY).getBooleanValue();
        if(request.getIsUseIntegral() && !integralDeductionEnabled){
            return ResponseValue.error("积分抵扣未开启,无法使用积分");
        }
 
        long userId = this.getCurrentUserId();
        EbUser user = this.getUserRegCache().get(userId);
        ComputedOrderPriceResponse response = this.doComputePrice(request, preOrderVo, userId, user.getIntegral(), integralDeductionEnabled);
        return ResponseValue.success(response);
    }
 
    /**
     * 检查门店自提是否合法
     * @param orderMerchantRequestList
     */
    private void checkIsTakeTheir(List<OrderMerchantRequest> orderMerchantRequestList){
        for(OrderMerchantRequest orderMerchantRequest : orderMerchantRequestList){
            if(orderMerchantRequest.getShippingType().intValue() == OrderConstants.ORDER_SHIPPING_TYPE_PICK_UP
                    && this.getMerchantCache().get(orderMerchantRequest.getMerId()).getIsTakeTheir() == 0){
                throw new PlatformRuntimeException("商户未开启门店自提功能");
            }
        }
    }
 
    /**
     * 计算订单金额
     * @param request
     * @param preOrderVo 预下单对象
     * @param userId 用户ID
     * @param integral 用户总积分
     * @param integralDeductionEnabled 是否允许积分抵扣
     * @return
     */
    private ComputedOrderPriceResponse doComputePrice(OrderComputedPriceRequest request, PreOrderVo preOrderVo
            , long userId, int integral, boolean integralDeductionEnabled){
        // 计算各种价格
        ComputedOrderPriceResponse priceResponse = new ComputedOrderPriceResponse();
        List<OrderMerchantRequest> orderMerchantRequestList = request.getOrderMerchantRequestList();
        for(PreMerchantOrderVo merchantOrderVo : preOrderVo.getMerchantOrderVoList()){
            for(OrderMerchantRequest o : orderMerchantRequestList){
                if(o.getMerId().intValue() == merchantOrderVo.getMerId().intValue()){
                    merchantOrderVo.setShippingType(o.getShippingType());
                    merchantOrderVo.setUserCouponId(o.getUserCouponId());
                }
            }
        }
        EbUserAddress userAddress = null;
        boolean autoShippingDone = this.isAutoShippingDone(preOrderVo.getMerchantOrderVoList());
        if(!autoShippingDone){
            // 2023-09-09 实物商品,正常发货
            userAddress = this.getUserAddressService().get(new EbUserAddress(request.getAddressId()));
        }
        this.doComputeFreightFee(preOrderVo, userAddress, autoShippingDone);
        priceResponse.setFreightFee(preOrderVo.getFreightFee());
 
        // 优惠券计算
        acquireCouponFee(preOrderVo, orderMerchantRequestList, userId);
        priceResponse.setCouponFee(preOrderVo.getCouponFee());
 
        List<ComputedMerchantOrderResponse> merOrderResponseList = new ArrayList<>(preOrderVo.getMerchantOrderVoList().size());
        ComputedMerchantOrderResponse computedMerchantOrder = null;
        for(PreMerchantOrderVo merchantOrderVo : preOrderVo.getMerchantOrderVoList()){
            computedMerchantOrder = new ComputedMerchantOrderResponse();
            computedMerchantOrder.setMerId(merchantOrderVo.getMerId());
            computedMerchantOrder.setCouponFee(merchantOrderVo.getCouponFee());
            computedMerchantOrder.setFreightFee(merchantOrderVo.getFreightFee());
            computedMerchantOrder.setUserCouponId(merchantOrderVo.getUserCouponId());
        }
        priceResponse.setMerOrderResponseList(merOrderResponseList);
 
        // 积分部分
        double integralDeductionStartMoney = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_START_MONEY).getDoubleValue();
        Double payPrice = preOrderVo.getProTotalFee() - priceResponse.getCouponFee();   // 实际支付金额
        priceResponse.setIsUseIntegral(request.getIsUseIntegral()); // 是否使用积分
        priceResponse.setProTotalFee(preOrderVo.getProTotalFee());  // 支付总费用
        if (!request.getIsUseIntegral() || integral <= 0) {// 不使用积分
            priceResponse.setDeductionPrice(0d);
            priceResponse.setSurplusIntegral(integral); // 剩余积分
            priceResponse.setPayFee(payPrice + priceResponse.getFreightFee());
            priceResponse.setUsedIntegral(0);
            priceResponse.setIntegralDeductionSwitch(false);
            priceResponse.setIsUseIntegral(false);
            if (integralDeductionEnabled && payPrice >= integralDeductionStartMoney) {
                priceResponse.setIntegralDeductionSwitch(true);
            }
            return priceResponse;
        }
 
        // 使用积分
        if (request.getIsUseIntegral() && integral > 0) {
            if(integralDeductionStartMoney <= 0 || payPrice < integralDeductionStartMoney){
                priceResponse.setDeductionPrice(0d);
                priceResponse.setSurplusIntegral(integral);
                priceResponse.setPayFee(payPrice + priceResponse.getFreightFee());
                priceResponse.setUsedIntegral(0);
                priceResponse.setIntegralDeductionSwitch(false);
                priceResponse.setIsUseIntegral(false);
                return priceResponse;
            }
 
            // 查询积分使用比例
            double integralRatio = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_RATIO).getDoubleValue();
            // 可抵扣金额(支付总额中能被抵扣的金额)
//            BigDecimal canDeductionPrice = payPrice.multiply(new BigDecimal(integralRatio)).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_DOWN);
            double canDeductionPrice = NumberFormatUtils.scaleAccuracy2((payPrice * integralRatio) / 100);
            // 积分转换金额
            double integralDeductionMoney = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_MONEY).getDoubleValue();
//            BigDecimal deductionPrice = new BigDecimal(user.getIntegral()).multiply(new BigDecimal(integralDeductionMoney));
            // 用户总积分可兑换金额
            double deductionPrice = integral * integralDeductionMoney;
            // 积分兑换金额小于实际支付可抵扣金额
            if (deductionPrice <= canDeductionPrice) {
//                payPrice = payPrice.subtract(deductionPrice);
                priceResponse.setSurplusIntegral(0);
                priceResponse.setUsedIntegral(integral);
            } else {
                deductionPrice = canDeductionPrice;
                if (canDeductionPrice > 0) {
//                    int usedIntegral = canDeductionPrice.divide(new BigDecimal(integralDeductionMoney), 0, BigDecimal.ROUND_UP).intValue();
                    int usedIntegral = new Double(Math.round((canDeductionPrice / integralDeductionMoney))).intValue();
                    priceResponse.setSurplusIntegral(integral - usedIntegral);
                    priceResponse.setUsedIntegral(usedIntegral);
                }
            }
//            payPrice = payPrice.subtract(deductionPrice);
            payPrice = payPrice - deductionPrice;
            priceResponse.setPayFee(payPrice + priceResponse.getFreightFee());
            priceResponse.setDeductionPrice(deductionPrice);
            priceResponse.setIsUseIntegral(true);
            priceResponse.setIntegralDeductionSwitch(true);
        }
        return priceResponse;
    }
 
    /**
     * 获取优惠金额,还未实现。
     * @param orderInfoVo
     * @param orderMerchantRequestList
     * @param uid
     */
    private void acquireCouponFee(PreOrderVo orderInfoVo, List<OrderMerchantRequest> orderMerchantRequestList, Long uid) {
        logger.warn("FrontOrderServiceImpl.getCouponFee()");
    }
 
    /**
     * 计算订单运费,暂时未实现。后续要加上
     * @param preOrderVo
     * @param userAddress
     * @date 2023-07-07
     */
    private void doComputeFreightFee(PreOrderVo preOrderVo, EbUserAddress userAddress, boolean autoShippingDone) {
        logger.warn("FrontOrderServiceImpl.getFreightFee()");
    }
 
    /**
     * 订单列表
     * @param status 订单状态(-1:全部,0:待支付,1:待发货,2:部分发货, 3:待核销,4:待收货,5:已收货,6:已完成,9:已取消)
     * @return
     * @date 2023-07-07
     */
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    public ResponseValue orderList(Integer status){
        long userId = this.getCurrentUserId();
        GenericPager<EbOrder> pager = this.getOrderService().queryUserOrderList(userId, status);
        List<EbOrder> orderList = pager.getDatas();
        if(StringUtils.isEmptyList(orderList)){
            return ResponseValue.success(pager);
        }
        List<OrderFrontVo> responseList = new ArrayList<>(4);
        OrderFrontVo orderFrontVo = null;
        for(EbOrder order : orderList){
            orderFrontVo = VoUtils.acquireOrderFrontVo(order);
            // 订单详情对象列表
            List<EbOrderDetail> orderDetailList = this.getOrderService().queryOrderDetailList(order.getOrderNo());
            List<OrderDetailFrontVo> infoResponseList = new ArrayList<>(4);
            OrderDetailFrontVo detailFrontVo = null;
            for(EbOrderDetail detail : orderDetailList){
                detailFrontVo = com.ishop.merchant.util.VoUtils.acquireOrderDetailFrontVo(detail);
                infoResponseList.add(detailFrontVo);
            }
            orderFrontVo.setOrderInfoList(infoResponseList);
            if(order.getMerId() != null && order.getMerId().intValue() > 0){
                orderFrontVo.setMerName(this.getMerchantCache().get(order.getMerId()).getName());
            }
            responseList.add(orderFrontVo);
        }
        return ResponseValue.success(ListPageContext.createGenericPager(responseList, pager.getPageIndex(), pager.getPageSize(), (int)pager.getTotalRows()));
    }
 
    /**
     * 加载预下单
     * @return
     */
    @RequestMapping(value = "/load/pre/{preOrderNo}", method = RequestMethod.GET)
    public ResponseValue loadPreOrder(@PathVariable String preOrderNo){
        if(StringUtils.isEmpty(preOrderNo)){
            return ResponseValue.error(Constants.ERROR_ARGUMENT);
        }
        PreOrderVo vo = this.getPreOrderCache().get(preOrderNo);
        if(vo == null){
            return ResponseValue.error("预下单信息不存在");
        }
 
        PreOrderResponse response = new PreOrderResponse();
        response.setOrderInfoVo(vo);
        return ResponseValue.success(response);
    }
 
    /**
     * 预下单
     * @return
     * @date 2023-07-06
     */
    @RequestMapping(value = "/pre/order", method = RequestMethod.POST)
    public ResponseValue preOrder(@RequestBody PreOrderRequest request){
        if(request == null || StringUtils.isEmpty(request.getPreOrderType())){
            return ResponseValue.error(Constants.ERROR_ARGUMENT);
        }
        if(this.logger.isDebugEnabled()){
            try {
                logger.debug("预下单 = {}", JsonUtils.objectToJsonString(request));
            } catch (Exception e) {
                logger.warn("PreOrderRequest -> JSON 错误:" + e.getMessage());
            }
        }
 
        EbUser user = this.getUserRegCache().get(this.getCurrentUserId());
 
        PreOrderVo preOrderInfoVo = OrderUtils.validatePreOrderRequest(request, this.getCdnUrl());
        List<PreOrderDetailVo> orderInfoList = new ArrayList<>(4);
        for (PreMerchantOrderVo merchantOrderVo : preOrderInfoVo.getMerchantOrderVoList()) {
            orderInfoList.addAll(merchantOrderVo.getOrderInfoList());
            double merTotalPrice = 0;
            for(PreOrderDetailVo e: merchantOrderVo.getOrderInfoList()){
                merTotalPrice += e.getPrice() * e.getPayNum();
            }
            merchantOrderVo.setProTotalFee(merTotalPrice);
            merchantOrderVo.setProTotalNum(merchantOrderVo.getOrderInfoList().stream().mapToInt(PreOrderDetailVo::getPayNum).sum());
        }
        // 商品总计金额
        double totalPrice = 0;
        for(PreOrderDetailVo e : orderInfoList){
            totalPrice += e.getPrice() * e.getPayNum();
        }
        preOrderInfoVo.setProTotalFee(totalPrice);
        // 购买商品总数量
        int orderProNum = orderInfoList.stream().mapToInt(PreOrderDetailVo::getPayNum).sum();
        preOrderInfoVo.setOrderProNum(orderProNum);
 
        // 获取默认地址
//        UserAddress userAddress = userAddressService.getDefaultByUid(user.getId());
//        if (ObjectUtil.isNotNull(userAddress)) {
//            // 计算运费
//            getFreightFee(preOrderInfoVo, userAddress);
//            preOrderInfoVo.setAddressId(userAddress.getId());
//        } else {
//            preOrderInfoVo.setFreightFee(BigDecimal.ZERO);
//            preOrderInfoVo.setAddressId(0);
//        }
        preOrderInfoVo.setFreightFee(0d);
        preOrderInfoVo.setAddressId(0);
 
        // 实际支付金额
        preOrderInfoVo.setPayFee(preOrderInfoVo.getProTotalFee() + preOrderInfoVo.getFreightFee());
        preOrderInfoVo.setUserIntegral(user.getIntegral());
        preOrderInfoVo.setUserBalance(user.getNowMoney().doubleValue());
        preOrderInfoVo.setIntegralDeductionSwitch(false);
        preOrderInfoVo.setIsUseIntegral(false);
        boolean integralDeductionEnabled = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_SWITCH).getBooleanValue();
        double integralDeductionStartMoney = this.getArgumentVariable(com.ishop.merchant.Constants.CONFIG_KEY_INTEGRAL_DEDUCTION_START_MONEY).getDoubleValue();
        if (integralDeductionEnabled && preOrderInfoVo.getProTotalFee() >= integralDeductionStartMoney) {
            preOrderInfoVo.setIntegralDeductionSwitch(true);
        }
 
        // 2023-09-09
        boolean autoShippingDone = this.isAutoShippingDone(preOrderInfoVo.getMerchantOrderVoList());
        preOrderInfoVo.setAutoShippingDone(autoShippingDone);
 
        // 缓存订单
        String key = new StringBuilder(user.getId().toString()).append(NumberGenerator.getLongSequenceNumber()).toString();
//        String key = user.getId() + CrmebDateUtil.getNowTime().toString() + CrmebUtil.getUuid();
        this.getPreOrderCache().save(key, preOrderInfoVo, OrderConstants.PRE_ORDER_CACHE_TIME);
        OrderNoVo response = new OrderNoVo();
        response.setOrderNo(key);
        response.setOrderType(preOrderInfoVo.getType());
        try {
            logger.info("preOrder response:{}", JsonUtils.objectToJsonString(response));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return ResponseValue.success(response);
    }
}