package com.hzs.sale.deliver.controller.manage;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hzs.common.core.annotation.AccessPermissions;
import com.hzs.common.core.annotation.Log;
import com.hzs.common.core.annotation.RepeatSubmitSimple;
import com.hzs.common.core.constant.CountryConstants;
import com.hzs.common.core.constant.EnumsPrefixConstants;
import com.hzs.common.core.constant.msg.SaOrderMsgConstants;
import com.hzs.common.core.enums.*;
import com.hzs.common.core.utils.DateUtils;
import com.hzs.common.core.utils.StringUtils;
import com.hzs.common.core.utils.poi.ExcelUtil;
import com.hzs.common.core.web.controller.BaseController;
import com.hzs.common.core.web.domain.AjaxResult;
import com.hzs.common.core.web.page.TableDataInfo;
import com.hzs.common.domain.sale.deliver.SaDeliver;
import com.hzs.common.domain.sale.deliver.SaDeliverBarCode;
import com.hzs.common.security.utils.SecurityUtils;
import com.hzs.common.service.ITransactionCommonService;
import com.hzs.common.util.TransactionUtils;
import com.hzs.sale.deliver.param.*;
import com.hzs.sale.deliver.service.ISaDeliverBarCodeService;
import com.hzs.sale.deliver.service.ISaDeliverItemsService;
import com.hzs.sale.deliver.service.ISaDeliverService;
import com.hzs.sale.deliver.vo.*;
import com.hzs.sale.util.OrderUtil;
import com.hzs.system.base.IAreaServiceApi;
import com.hzs.system.base.IBarCodeServiceApi;
import com.hzs.system.base.dto.BarCodeDTO;
import com.hzs.system.sys.IUserServiceApi;
import com.hzs.system.sys.dto.UserAuthorityDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 发货清单已合单控制器
 * @Author: jiang chao
 * @Time: 2022/10/19 16:43
 * @Classname: SaDeliverController
 * @PackageName: com.hzs.sale.order.controller.manager
 */
@RestController
@RequestMapping("/manage/deliver-handled")
public class SaDeliverHandledController extends BaseController {

    @Autowired
    private ISaDeliverService iSaDeliverService;
    @Autowired
    private ISaDeliverItemsService iSaDeliverItemsService;
    @Autowired
    private ISaDeliverBarCodeService iSaDeliverBarCodeService;
    @Autowired
    private ITransactionCommonService iTransactionCommonService;

    @DubboReference
    IAreaServiceApi iAreaServiceApi;
    @DubboReference
    IBarCodeServiceApi iBarCodeServiceApi;
    @DubboReference
    IUserServiceApi iUserServiceApi;

    /**
     * 列表
     *
     * @param param 已合单列表查询入参
     * @return
     */
    @AccessPermissions("DeliveryHandled")
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.SELECT)
    @GetMapping("/list")
    public TableDataInfo list(DeliverHandledParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getPayTime());

        Integer pkCountry = SecurityUtils.getPkCountry();

        // 返回数据
        List<DeliverHandledVO> resultList = new ArrayList<>();

        if (StringUtils.isNotEmpty(param.getBarCode())) {
            // 追溯条码处理
            LambdaQueryWrapper<SaDeliverBarCode> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SaDeliverBarCode::getPkCountry, pkCountry);
            queryWrapper.eq(SaDeliverBarCode::getBarCode, param.getBarCode());
            List<SaDeliverBarCode> barCodeList = iSaDeliverBarCodeService.list(queryWrapper);
            if (CollectionUtil.isEmpty(barCodeList)) {
                // 带有追溯码查询条件，并没有查出来追溯码，则直接返回空数据
                return getDataTable(resultList);
            }
            param.setPkDeliver(barCodeList.get(0).getPkDeliver());
            param.setPkDeliverItems(barCodeList.get(0).getPkDeliverItems());
        }

        // 获取管理员权限（角色地区范围、体系列表、团队列表）
        UserAuthorityDTO userAuthorityDTO = iUserServiceApi.getUserAuthority(SecurityUtils.getUserId()).getData();
        param.setAreaScopeList(userAuthorityDTO.getRoleAreaScopeList());
        param.setVertexIdList(userAuthorityDTO.getVertexIdList());
        param.setTeamList(userAuthorityDTO.getUserTeamList());

        startPage();
        resultList = iSaDeliverService.queryDeliverHandledList(param, pkCountry);

        // 当查询有数据才进行处理
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAllAreaNoCache(pkCountry).getData();

            // 发货单明细ID
            List<Long> deliverItemsIdList = resultList.stream().map(DeliverHandledVO::getPkId).collect(Collectors.toList());
            // 根据发货单明细ID，查询对应绑定条码数据
            Map<Long, SaDeliverBarCode> barCodeMap = iSaDeliverBarCodeService.queryListByDeliverItems(deliverItemsIdList, pkCountry);

            for (DeliverHandledVO deliverHandled : resultList) {
                // 省市区处理
                OrderUtil.handleOrderAddress(areaMap, deliverHandled);

                // 处理追溯编号、扫码时间
                SaDeliverBarCode deliverBarCode = barCodeMap.get(deliverHandled.getPkId());
                if (null != deliverBarCode) {
                    deliverHandled.setBarCode(deliverBarCode.getBarCode());
                    deliverHandled.setScanTime(deliverBarCode.getCreationTime());
                }
            }
        }
        return getDataTable(resultList);
    }

    /**
     * 导出
     *
     * @param response
     * @param param    已合单列表查询入参
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DeliverHandledParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getPayTime());

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverHandledVO> resultList = new ArrayList<>();

        if (StringUtils.isNotEmpty(param.getBarCode())) {
            // 追溯条码处理
            LambdaQueryWrapper<SaDeliverBarCode> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SaDeliverBarCode::getPkCountry, pkCountry);
            queryWrapper.eq(SaDeliverBarCode::getBarCode, param.getBarCode());
            List<SaDeliverBarCode> barCodeList = iSaDeliverBarCodeService.list(queryWrapper);
            if (CollectionUtil.isEmpty(barCodeList)) {
                // 带有追溯码查询条件，并没有查出来追溯码，则直接返回空数据
                ExcelUtil<DeliverHandledVO> util = new ExcelUtil<>(DeliverHandledVO.class);
                util.exportExcel(response, resultList, "发货清单已合单导出");
                return;
            }
            param.setPkDeliver(barCodeList.get(0).getPkDeliver());
            param.setPkDeliverItems(barCodeList.get(0).getPkDeliverItems());
        }

        // 获取管理员权限（角色地区范围、体系列表、团队列表）
        UserAuthorityDTO userAuthorityDTO = iUserServiceApi.getUserAuthority(SecurityUtils.getUserId()).getData();
        param.setAreaScopeList(userAuthorityDTO.getRoleAreaScopeList());
        param.setVertexIdList(userAuthorityDTO.getVertexIdList());
        param.setTeamList(userAuthorityDTO.getUserTeamList());

        resultList = iSaDeliverService.queryDeliverHandledList(param, pkCountry);

        // 当查询有数据才进行处理
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAllAreaNoCache(pkCountry).getData();

            // 发货单明细ID
            List<Long> deliverItemsIdList = resultList.stream().map(DeliverHandledVO::getPkId).collect(Collectors.toList());
            // 根据发货单明细ID，查询对应绑定条码数据
            Map<Long, SaDeliverBarCode> barCodeMap = iSaDeliverBarCodeService.queryListByDeliverItems(deliverItemsIdList, pkCountry);

            // 获取需要翻译的枚举翻译
            Map<String, String> transactionMap = iTransactionCommonService.exportEnumTransaction(EDelivery.values(), EOrderStatus.values(),
                    EOrderType.values(), EDeliveryStatus.values(), ESupplyWay.values(), ETransportType.values(), EPresaleStatus.values(),
                    EPrintStatus.values(), EShippingChannel.values(), EYesNo.values());

            for (DeliverHandledVO deliverHandled : resultList) {
                // 省市区处理
                OrderUtil.handleOrderAddress(areaMap, deliverHandled);

                deliverHandled.setOrderStatusVal(transactionMap.get(EnumsPrefixConstants.ORDER_STATUS + deliverHandled.getOrderStatus()));
                deliverHandled.setOrderTypeVal(transactionMap.get(EnumsPrefixConstants.ORDER_TYPE + deliverHandled.getOrderType()));
                deliverHandled.setDeliveryWayVal(transactionMap.get(EnumsPrefixConstants.DELIVERY + deliverHandled.getDeliveryWay()));
                deliverHandled.setOperateScopeVal(transactionMap.get(EnumsPrefixConstants.SUPPLY_WAY + deliverHandled.getOperateScope()));
                deliverHandled.setPreSaleStatusVal(transactionMap.get(EnumsPrefixConstants.PRESALE_STATUS + deliverHandled.getPreSaleStatus()));
                deliverHandled.setPrintStatusVal(transactionMap.get(EnumsPrefixConstants.E_PRINT_STATUS + deliverHandled.getPrintStatus()));
                deliverHandled.setTranTypeVal(transactionMap.get(EnumsPrefixConstants.ENU_TRA + deliverHandled.getTranType()));
                deliverHandled.setShippingChannelVal(transactionMap.get(EnumsPrefixConstants.E_SHIPPING_CHANNEL + deliverHandled.getShippingChannel()));
                deliverHandled.setIsBarCodeVal(transactionMap.get(EnumsPrefixConstants.YES_NO + deliverHandled.getIsBarCode()));

                deliverHandled.setRecAddress(deliverHandled.getRecProvinceVal()
                        + (StringUtils.isNotEmpty(deliverHandled.getRecCityVal()) ? deliverHandled.getRecCityVal() : "")
                        + (StringUtils.isNotEmpty(deliverHandled.getRecCountyVal()) ? deliverHandled.getRecCountyVal() : "")
                        + deliverHandled.getRecAddress());

                // 处理追溯编号、扫码时间
                SaDeliverBarCode deliverBarCode = barCodeMap.get(deliverHandled.getPkId());
                if (null != deliverBarCode) {
                    deliverHandled.setBarCode(deliverBarCode.getBarCode());
                    deliverHandled.setScanTime(deliverBarCode.getCreationTime());
                }
            }
        }
        ExcelUtil<DeliverHandledVO> util = new ExcelUtil<>(DeliverHandledVO.class);
        util.exportExcel(response, resultList, "发货清单已合单导出");
    }

    /**
     * 仓储导出
     *
     * @param response
     * @param param
     */
    @PostMapping("/wms-export")
    public void wmsExport(HttpServletResponse response, DeliverHandledParam param) {
        DateUtils.handTimeStartAndEnd(param.getCreationTime());
        DateUtils.handTimeStartAndEnd(param.getPayTime());

        // 国家ID
        Integer pkCountry = SecurityUtils.getPkCountry();

        List<DeliverWmsVO> voList = new ArrayList<>();

        if (StringUtils.isNotEmpty(param.getBarCode())) {
            // 追溯条码处理
            LambdaQueryWrapper<SaDeliverBarCode> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SaDeliverBarCode::getPkCountry, pkCountry);
            queryWrapper.eq(SaDeliverBarCode::getBarCode, param.getBarCode());
            List<SaDeliverBarCode> barCodeList = iSaDeliverBarCodeService.list(queryWrapper);
            if (CollectionUtil.isEmpty(barCodeList)) {
                // 带有追溯码查询条件，并没有查出来追溯码，则直接返回空数据
                ExcelUtil<DeliverWmsVO> util = new ExcelUtil<>(DeliverWmsVO.class);
                util.exportExcel(response, voList, "发货清单已合单导出");
                return;
            }
            param.setPkDeliver(barCodeList.get(0).getPkDeliver());
            param.setPkDeliverItems(barCodeList.get(0).getPkDeliverItems());
        }

        // 获取管理员权限（角色地区范围、体系列表、团队列表）
        UserAuthorityDTO userAuthorityDTO = iUserServiceApi.getUserAuthority(SecurityUtils.getUserId()).getData();
        param.setAreaScopeList(userAuthorityDTO.getRoleAreaScopeList());
        param.setVertexIdList(userAuthorityDTO.getVertexIdList());
        param.setTeamList(userAuthorityDTO.getUserTeamList());

        List<DeliverHandledVO> resultList = iSaDeliverService.queryDeliverHandledList(param, pkCountry);

        // 当查询有数据才进行处理
        if (resultList.size() > 0) {
            // 获取行政区划map
            Map<Integer, String> areaMap = iAreaServiceApi.getAllAreaNoCache(pkCountry).getData();

            String deliverCode = "";
            DeliverWmsVO vo = null;
            // 合并 key： 发货单号 + 仓储编号 + 规格，一样的累计数量
            String key = null;
            for (DeliverHandledVO deliverHandled : resultList) {
                if (null == key || !key.equals(deliverHandled.getDeliverCode() + "-" + deliverHandled.getWmsCode() + "-" + deliverHandled.getSpecsName())) {
                    // key： 发货单号 + 仓储编号 + 规格，一样的累计数量
                    key = deliverHandled.getDeliverCode() + "-" + deliverHandled.getWmsCode() + "-" + deliverHandled.getSpecsName();

                    vo = DeliverWmsVO.builder()
                            .wmsCode(deliverHandled.getWmsCode())
                            .productName(deliverHandled.getProductName())
                            .specsName(deliverHandled.getSpecsName())
                            .quantity(deliverHandled.getQuantity())
                            .price(BigDecimal.ZERO)
                            .build();
                    if (!deliverCode.equals(deliverHandled.getDeliverCode())) {
                        deliverCode = deliverHandled.getDeliverCode();
                        vo.setDeliverCode(deliverHandled.getDeliverCode());
                        vo.setRecName(deliverHandled.getRecName());
                        vo.setRecPhone(deliverHandled.getRecPhone());

                        // 省市区处理
                        OrderUtil.handleOrderAddress(areaMap, deliverHandled);
                        String address = deliverHandled.getRecProvinceVal()
                                + (StringUtils.isNotEmpty(deliverHandled.getRecCityVal()) ? deliverHandled.getRecCityVal() : "")
                                + (StringUtils.isNotEmpty(deliverHandled.getRecCountyVal()) ? deliverHandled.getRecCountyVal() : "")
                                + deliverHandled.getRecAddress();
                        vo.setRecAddress(address);
                    }
                    voList.add(vo);
                } else {
                    vo.setQuantity(vo.getQuantity() + deliverHandled.getQuantity());
                }
            }
        }
        ExcelUtil<DeliverWmsVO> util = new ExcelUtil<>(DeliverWmsVO.class);
        util.exportExcel(response, voList, "发货清单已合单导出");
    }

    /**
     * 打印货单
     *
     * @param deliverIdList 发货单ID列表
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.PRINT)
    @GetMapping("/print")
    public AjaxResult print(@RequestParam("deliverIdList") List<Long> deliverIdList) {

        Integer pkCountry = SecurityUtils.getPkCountry();

        if (CountryConstants.CHINA_COUNTRY.equals(pkCountry)) {
            // 中国使用新的打印模板
            // 返回数据
            List<DeliverPrintNewVO> resultList = new ArrayList<>();

            // 发货单打印数据（出库单汇总）
            List<DeliverPrintNewVO> dataList = iSaDeliverService.deliverPrintNew(deliverIdList, pkCountry, SecurityUtils.getUserId());

            if (dataList.size() > 0) {
                // 获取行政区划map
                Map<Integer, String> areaMap = iAreaServiceApi.getAllAreaNoCache(pkCountry).getData();

                // 发货单map（key:发货单编号， value：发货单实体）
                Map<String, DeliverPrintNewVO> deliverMap = new HashMap<>();
                // 会员编号
                String memberCode = null;
                // 发货单编号
                String deliverCode = null;
                // 发货单订单
                DeliverPrintNewOrderVO deliverPrintNewOrderVO = null;
                // 批次数据
                Map<Integer, Integer> batchMap = new HashMap<>();

                // 遍历处理数据封装
                for (DeliverPrintNewVO tmpDeliverPrintNewVO : dataList) {
                    Integer batchCount = batchMap.get(tmpDeliverPrintNewVO.getDayBatch());
                    if (null == batchCount) {
                        // 如果批次没有数据，需要查一下
                        batchCount = iSaDeliverService.getBatchMaxNumber(tmpDeliverPrintNewVO.getDayBatch());
                        batchMap.put(tmpDeliverPrintNewVO.getDayBatch(), batchCount);
                    }

                    DeliverPrintNewVO deliverPrintNewVO = deliverMap.get(tmpDeliverPrintNewVO.getDeliverCode());
                    if (null == deliverPrintNewVO) {
                        // 如果map中不存在，则创建一个新的发货单返回数据
                        deliverPrintNewVO = DeliverPrintNewVO.builder()
                                .deliverCode(tmpDeliverPrintNewVO.getDeliverCode())
                                .houseName(tmpDeliverPrintNewVO.getHouseName())
                                .payTime(tmpDeliverPrintNewVO.getPayTime())
                                .recName(tmpDeliverPrintNewVO.getRecName())
                                .recPhone(DesensitizedUtil.mobilePhone(tmpDeliverPrintNewVO.getRecPhone()))
                                .printTime(tmpDeliverPrintNewVO.getPrintTime())
                                .recProvinceVal(areaMap.get(tmpDeliverPrintNewVO.getRecProvince()))
                                .recCityVal(areaMap.get(tmpDeliverPrintNewVO.getRecCity()))
                                .recCountyVal(areaMap.get(tmpDeliverPrintNewVO.getRecCounty()))
                                .recAddress(tmpDeliverPrintNewVO.getRecAddress())
                                .dayBatch(tmpDeliverPrintNewVO.getDayBatch())
                                .batchNumber(tmpDeliverPrintNewVO.getBatchNumber())
                                .batchCount(batchCount)
                                .build();
                        // 创建发货单明细
                        deliverPrintNewVO.setItemList(new ArrayList<>());
                        // 创建发货单订单明细
                        deliverPrintNewVO.setOrderList(new ArrayList<>());

                        // 将返回发货单放到map中
                        deliverMap.put(tmpDeliverPrintNewVO.getDeliverCode(), deliverPrintNewVO);

                        resultList.add(deliverPrintNewVO);
                    }

                    // 产品是否已经存在
                    boolean isFlag = false;
                    // 处理产品累计处理
                    for (DeliverPrintNewItemVO deliverPrintNewItemVO : deliverPrintNewVO.getItemList()) {
                        if (tmpDeliverPrintNewVO.getProductName().equals(deliverPrintNewItemVO.getProductName())
                                && tmpDeliverPrintNewVO.getSpecsName().equals(deliverPrintNewItemVO.getSpecsName())) {
                            // 产品名称 和 产品规格 相同
                            // 数量累计，金额累计
                            deliverPrintNewItemVO.setQuantity(deliverPrintNewItemVO.getQuantity() + tmpDeliverPrintNewVO.getQuantity());
                            deliverPrintNewItemVO.setPrice(deliverPrintNewItemVO.getPrice().add(tmpDeliverPrintNewVO.getPrice()));
                            isFlag = true;
                        }
                    }
                    if (!isFlag) {
                        // 如果产品第一次在列表中出现，需要新添加
                        deliverPrintNewVO.getItemList().add(DeliverPrintNewItemVO.builder()
                                .productCode(tmpDeliverPrintNewVO.getProductCode())
                                .productName(tmpDeliverPrintNewVO.getProductName())
                                .specsName(tmpDeliverPrintNewVO.getSpecsName())
                                .unitTransaction(tmpDeliverPrintNewVO.getUnitTransaction())
                                .quantity(tmpDeliverPrintNewVO.getQuantity())
                                .price(tmpDeliverPrintNewVO.getPrice())
                                .build());
                    }

                    // 会员编号、发货单编号不等于现在数据编号，创建一个新的订单列表
                    if (!tmpDeliverPrintNewVO.getMemberCode().equals(memberCode)
                            || !tmpDeliverPrintNewVO.getDeliverCode().equals(deliverCode)) {
                        memberCode = tmpDeliverPrintNewVO.getMemberCode();
                        deliverCode = tmpDeliverPrintNewVO.getDeliverCode();
                        // 创建发货单订单
                        deliverPrintNewOrderVO = DeliverPrintNewOrderVO.builder()
                                .memberCode(tmpDeliverPrintNewVO.getMemberCode())
                                .memberName(tmpDeliverPrintNewVO.getMemberName())
                                .payTime(tmpDeliverPrintNewVO.getPayTime())
                                .houseName(tmpDeliverPrintNewVO.getHouseName())
                                .printTime(tmpDeliverPrintNewVO.getPrintTime())
                                .recName(tmpDeliverPrintNewVO.getRecName())
                                .recPhone(DesensitizedUtil.mobilePhone(tmpDeliverPrintNewVO.getRecPhone()))
                                .recProvinceVal(areaMap.get(tmpDeliverPrintNewVO.getRecProvince()))
                                .recCityVal(areaMap.get(tmpDeliverPrintNewVO.getRecCity()))
                                .recCountyVal(areaMap.get(tmpDeliverPrintNewVO.getRecCounty()))
                                .recAddress(tmpDeliverPrintNewVO.getRecAddress())
                                .build();

                        BeanUtil.copyProperties(tmpDeliverPrintNewVO, DeliverPrintNewOrderVO.class);
                        // 订单明细列表
                        deliverPrintNewOrderVO.setOrderItemsList(new ArrayList<>());

                        // 添加到发货单订单列表中
                        deliverPrintNewVO.getOrderList().add(deliverPrintNewOrderVO);
                    }
                    // 订单明细列表添加产品明细
                    deliverPrintNewOrderVO.getOrderItemsList().add(DeliverPrintNewItemVO.builder()
                            .orderCode(tmpDeliverPrintNewVO.getOrderCode())
                            .productCode(tmpDeliverPrintNewVO.getProductCode())
                            .productName(tmpDeliverPrintNewVO.getProductName())
                            .specsName(tmpDeliverPrintNewVO.getSpecsName())
                            .unitTransaction(tmpDeliverPrintNewVO.getUnitTransaction())
                            .quantity(tmpDeliverPrintNewVO.getQuantity())
                            .price(tmpDeliverPrintNewVO.getPrice())
                            .build());
                }
            }

            return AjaxResult.success(resultList);
        } else {
            // 海外目前不变
            // 返回数据
            List<DeliverPrintVO> resultList = new ArrayList<>();
            // 发货单打印数据
            List<DeliverPrintVO> dataList = iSaDeliverService.deliverPrint(deliverIdList, pkCountry, SecurityUtils.getUserId());

            if (dataList.size() > 0) {
                // 获取行政区划map
                Map<Integer, String> areaMap = iAreaServiceApi.getAllAreaNoCache(pkCountry).getData();

                // 遍历发货单，进行处理
                for (DeliverPrintVO deliverPrintVO : dataList) {
                    // 发货单打印明细列表
                    List<DeliverPrintItemVO> itemList = deliverPrintVO.getItemList();

                    // 发货单金额
                    BigDecimal deliverPrice = BigDecimal.ZERO;
                    for (DeliverPrintItemVO deliverPrintItemVO : itemList) {
                        deliverPrice = deliverPrice.add(deliverPrintItemVO.getPrice());
                    }
                    deliverPrintVO.setDeliverPrice(deliverPrice);

                    // 省市区处理
                    OrderUtil.handleOrderAddress(areaMap, deliverPrintVO);

                    resultList.add(deliverPrintVO);
                }
            }

            return AjaxResult.success(resultList);
        }
    }

    /**
     * 绑定条形码数据
     *
     * @param deliverIdList 发货单ID列表
     * @param orderIdList   订单ID列表
     * @return
     */
    @GetMapping("/code-bind-data")
    public AjaxResult codeBindData(@RequestParam("deliverIdList") List<Long> deliverIdList,
                                   @RequestParam(value = "orderIdList", required = false) List<Long> orderIdList) {
        Integer pkCountry = SecurityUtils.getPkCountry();

        // 返回最终结果
        List<DeliverBarCodeVO> resultList = new ArrayList<>();

        // 查询 发货单明细 + 已生成的条码
        List<DeliverBarCodeVO> deliverBarCodeVOList = iSaDeliverItemsService.deliverCodeData(deliverIdList, orderIdList, pkCountry, null);

        // 遍历发货明细列表
        for (DeliverBarCodeVO deliverBarCode : deliverBarCodeVOList) {
            // 发货明细对应的条码明细
            List<DeliverBarCodeDetailVO> detailList = deliverBarCode.getDetailList();

            // 遍历发货明细数量，填充已经绑定过的条码
            for (int i = 0; i < deliverBarCode.getQuantity(); i++) {
                // 发货条码ID
                Long deliverBarCodeId = null;
                // 条码
                String barCode = null;

                // 当前数量小于条码数量，则直接用条码内容，否则直接返回为空
                if (i < detailList.size()) {
                    deliverBarCodeId = detailList.get(i).getDeliverBarCodeId();
                    barCode = detailList.get(i).getBarCode();
                }

                // 生成最终要返回数据
                resultList.add(DeliverBarCodeVO.builder()
                        .pkId(deliverBarCode.getPkId())
                        .pkDeliver(deliverBarCode.getPkDeliver())
                        .pkOrder(deliverBarCode.getPkOrder())
                        .orderCode(deliverBarCode.getOrderCode())
                        .pkProduct(deliverBarCode.getPkProduct())
                        .productName(deliverBarCode.getProductName())
                        .specsName(deliverBarCode.getSpecsName())
                        .deliverBarCodeId(deliverBarCodeId)
                        .barCode(barCode)
                        .build());
            }
        }
        return AjaxResult.success(resultList);
    }

    /**
     * 绑定条码
     *
     * @param paramList 绑定条码参数
     * @return
     */
    @RepeatSubmitSimple
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.BIND)
    @PostMapping("/code-bind")
    public AjaxResult codeBind(@RequestBody List<BindCodeParam> paramList) {
        if (CollectionUtil.isEmpty(paramList)) {
            // 缺少参数
            return AjaxResult.error("缺少参数");
        }

        for (BindCodeParam bindCodeParam : paramList) {
            if (null == bindCodeParam.getPkDeliver() || null == bindCodeParam.getPkId() || null == bindCodeParam.getPkProduct()) {
                // 缺少参数
                return AjaxResult.error("缺少参数");
            }
        }

        // 获取条码不为空的数据
        List<BindCodeParam> paramNotEmptyList = paramList.stream().filter((param -> StringUtils.isNotEmpty(param.getBarCode()))).collect(Collectors.toList());
        // 校验条码是否重复（获取条码不为空并且去重复数量）
        if (paramNotEmptyList.size() != paramNotEmptyList.stream().distinct().count()) {
            // 追溯码存在重复
            return AjaxResult.error(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_CHECK_BARCODE_REPEAT));
        }

        // 只保留变动过数据，未变动数据不做处理
        paramNotEmptyList = paramNotEmptyList.stream().filter(param -> null == param.getDeliverBarCodeId()).collect(Collectors.toList());
        // 获取入参中的新条码
        List<String> barCodeStrList = paramNotEmptyList.stream().map(BindCodeParam::getBarCode).collect(Collectors.toList());
        if (barCodeStrList.size() == 0) {
            return AjaxResult.success();
        }

        Integer pkCountry = SecurityUtils.getPkCountry();

        // 查询已打印未使用的条码数据
        List<BarCodeDTO> barCodeList = iBarCodeServiceApi.queryPrintBarCode(barCodeStrList, pkCountry).getData();
        if (barCodeList.size() < barCodeStrList.size()) {
            // 追溯码不存在
            return AjaxResult.error(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_CHECK_BARCODE_NOT_EXIST));
        }

        barCodeList = barCodeList.stream().filter((barCodeDTO) -> EBarcodeStatus.BOUND.getValue() != barCodeDTO.getCodeStatus()).collect(Collectors.toList());
        if (barCodeList.size() < barCodeStrList.size()) {
            // 追溯码已使用
            return AjaxResult.error(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_CHECK_BARCODE_USED));
        }

        // 遍历入参以及条码数据，赋值条码ID用以保存，并且校验条码与产品是否一致
        for (BindCodeParam bindCodeParam : paramNotEmptyList) {
            for (BarCodeDTO barCodeDTO : barCodeList) {
                if (bindCodeParam.getBarCode().equals(barCodeDTO.getBarCode())) {
                    if (!bindCodeParam.getPkProduct().equals(barCodeDTO.getPkProduct())) {
                        // 追溯码与产品不对应
                        return AjaxResult.error(bindCodeParam.getBarCode() + TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_CHECK_BARCODE_NOT));
                    }
                    // 赋值条码ID用以保存
                    bindCodeParam.setDeliverBarCodeId(barCodeDTO.getPkId());
                    break;
                }
            }
        }

        // 绑定条码
        iSaDeliverBarCodeService.codeBind(paramNotEmptyList, SecurityUtils.getUserId(), pkCountry);
        return AjaxResult.success();
    }

    /**
     * 重置条码
     *
     * @param param 发货条码ID参数
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.UNBIND, remark = "重置条码")
    @PutMapping("/code-reset")
    public AjaxResult codeReset(@RequestBody ResetCodeParam param) {
        // 条码ID
        Long barCodeId = param.getBarCodeId();
        if (null == barCodeId) {
            // 缺少参数
            return AjaxResult.error("缺少参数");
        }
        // 重置条码
        iSaDeliverBarCodeService.codeReset(barCodeId, SecurityUtils.getPkCountry(), SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    /**
     * 解绑条形码数据
     *
     * @param deliverIdList 发货单ID列表
     * @return
     */
    @GetMapping("/code-unbind-data")
    public AjaxResult codeUnbindData(@RequestParam("deliverIdList") List<Long> deliverIdList) {
        Integer pkCountry = SecurityUtils.getPkCountry();

        // 返回最终结果
        List<DeliverBarCodeVO> resultList = new ArrayList<>();

        // 只查询 发货单明细 + 已生成的条码
        List<DeliverBarCodeVO> deliverBarCodeVOList = iSaDeliverItemsService.deliverCodeData(deliverIdList, null, pkCountry, EYesNo.YES.getIntValue());

        // 遍历发货明细列表
        for (DeliverBarCodeVO deliverBarCode : deliverBarCodeVOList) {
            // 发货明细对应的条码明细
            List<DeliverBarCodeDetailVO> detailList = deliverBarCode.getDetailList();

            // 遍历发货明细数量，填充已经绑定过的条码
            for (DeliverBarCodeDetailVO deliverBarCodeDetailVO : detailList) {
                // 生成最终要返回数据
                resultList.add(DeliverBarCodeVO.builder()
                        .pkId(deliverBarCode.getPkId())
                        .pkDeliver(deliverBarCode.getPkDeliver())
                        .orderCode(deliverBarCode.getOrderCode())
                        .pkProduct(deliverBarCode.getPkProduct())
                        .productName(deliverBarCode.getProductName())
                        .specsName(deliverBarCode.getSpecsName())
                        .deliverBarCodeId(deliverBarCodeDetailVO.getDeliverBarCodeId())
                        .barCode(deliverBarCodeDetailVO.getBarCode())
                        .build());
            }
        }

        return AjaxResult.success(resultList);
    }

    /**
     * 解绑条码
     *
     * @param paramList 发货条码ID列表
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.UNBIND)
    @PutMapping("/code-unbind")
    public AjaxResult unbindCode(@RequestBody List<Integer> paramList) {
        if (CollectionUtil.isEmpty(paramList)) {
            // 缺少参数
            return AjaxResult.error("缺少参数");
        }
        // 解绑条码
        iSaDeliverBarCodeService.codeClear(paramList, SecurityUtils.getPkCountry(), SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    /**
     * 删除发货单明细
     *
     * @param id 发货明细ID
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.DELETE, remark = "删除发货明细")
    @DeleteMapping("/delete-deliver-items")
    public AjaxResult deleteDeliverItems(@RequestParam Long id) {
        SaDeliver saDeliver = iSaDeliverService.queryDeliverByItems(id, SecurityUtils.getPkCountry());
        if (null == saDeliver) {
            // 发货单不存在
            return AjaxResult.error(TransactionUtils.getContent(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_NOT_EXIST)));
        }
        if (EDeliveryStatus.NOT_DELIVERY.getValue() != saDeliver.getDeliverStatus()) {
            // 发货单已发货
            return AjaxResult.error(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_SHIPPED));
        }
        iSaDeliverService.deleteDeliverItems(saDeliver, id, SecurityUtils.getPkCountry(), SecurityUtils.getUserId());
        return AjaxResult.success();
    }

    /**
     * 删除发货单
     *
     * @param idList 发货单ID列表
     * @return
     */
    @Log(module = EOperationModule.DELIVER_ORDER, business = EOperationBusiness.DELIVER_HANDLED, method = EOperationMethod.DELETE, remark = "删除发货单")
    @DeleteMapping("/delete-deliver")
    public AjaxResult deleteDeliver(@RequestParam List<Long> idList) {
        List<SaDeliver> deliverList = iSaDeliverService.queryListById(idList, SecurityUtils.getPkCountry());
        if (CollectionUtils.isEmpty(deliverList)) {
            // 发货单不存在
            return AjaxResult.error(TransactionUtils.getContent(TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_NOT_EXIST)));
        }
        for (SaDeliver saDeliver : deliverList) {
            if (EDeliveryStatus.NOT_DELIVERY.getValue() != saDeliver.getDeliverStatus()) {
                // 发货单已发货
                return AjaxResult.error(saDeliver.getDeliverCode() + TransactionUtils.getContent(SaOrderMsgConstants.DELIVER_SHIPPED));
            }
        }
        iSaDeliverService.deleteDeliver(deliverList, idList, SecurityUtils.getPkCountry(), SecurityUtils.getUserId());
        return AjaxResult.success();
    }

}
