package cn.superdesk.uniorder.service.order.base.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.superdesk.uniorder.common.enums.common.CommonAccountingStateEnum;
import cn.superdesk.uniorder.common.enums.login.SysLoginTypeEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderBackStatusEnum;
import cn.superdesk.uniorder.common.enums.order.UnifiedOrderInvoiceStateEnum;
import cn.superdesk.uniorder.common.json.AnJsonUtils;
import cn.superdesk.uniorder.common.lamda.AnLamdaUtils;
import cn.superdesk.uniorder.common.numerical.AnIntegerUtils;
import cn.superdesk.uniorder.common.numerical.AnLongUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.common.security.sensitive.DesensitizedUtils;
import cn.superdesk.uniorder.common.security.sensitive.constants.SensitiveRequireSwitchEnum;
import cn.superdesk.uniorder.dao.convert.DtoSugarUpUtils;
import cn.superdesk.uniorder.dao.entity.accounting.unified.customer.AccountingUnifiedCustomerOrder;
import cn.superdesk.uniorder.dao.entity.accounting.unified.supplier.AccountingUnifiedSupplierXGoods;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrder;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderExample;
import cn.superdesk.uniorder.dao.entity.base.UnifiedOrderGoods;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApply;
import cn.superdesk.uniorder.dao.entity.invoice.customer.InvoiceApplyXGoods;
import cn.superdesk.uniorder.dao.mapper.base.*;
import cn.superdesk.uniorder.dao.mapper.channel.UnifiedChannelProfitSyncMapper;
import cn.superdesk.uniorder.dao.mapper.channel.UnifiedChannelProfitSyncMapperEx;
import cn.superdesk.uniorder.dao.mapper.unified.UnifiedOrderProfitMapper;
import cn.superdesk.uniorder.dao.mapper.unified.UnifiedOrderProfitMapperEx;
import cn.superdesk.uniorder.dto.param._function.select.SelectOptionDepartmentCriteria;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.AccountingSupplierNotYetDimGoodsQueryCriteria;
import cn.superdesk.uniorder.dto.param.accounting.unified.supplier.SuplierStatementOfAccountDetailQueryCriteria;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionDepartment;
import cn.superdesk.uniorder.dto.vo._function.select.SelectOptionVirt;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.notyet.CustomerUnAccountingDimGoodsVo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.notyet.UnifiedOrderCustomerHeadSumVo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.customer.notyet.UnifiedOrderCustomerNotCheckVo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.supplier.notyet.UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo;
import cn.superdesk.uniorder.dto.vo.accounting.unified.supplier.notyet.UnifiedOrderSupplierHeadSumVo;
import cn.superdesk.uniorder.dto.vo.order.Org2VirtStatisticsVo;
import cn.superdesk.uniorder.dto.vo.setting.UnifiedServiceCacheStruct;
import cn.superdesk.uniorder.dto.vo.unified.UnifiedOrderCommonHeadSum;
import cn.superdesk.uniorder.dto.vo.unified.UnifiedOrderGoodsVo;
import cn.superdesk.uniorder.dto.vo.unified.UnifiedOrderSupplierDimOrderNotCheckVo;
import cn.superdesk.uniorder.dto.vo.unified.UnifiedOrderSupplierNotCheckDetail2GoodsVo;
import cn.superdesk.uniorder.dto.vo.wechat.WxBillOrder;
import cn.superdesk.uniorder.event.CommonEventPublisher;
import cn.superdesk.uniorder.service.accounting.unified.customer.AccountingUnifiedCustomerOrderService;
import cn.superdesk.uniorder.service.accounting.unified.supplier.AccountingUnifiedSupplierXGoodsService;
import cn.superdesk.uniorder.service.invoice.customer.InvoiceApplyCustomerService;
import cn.superdesk.uniorder.service.order.base.*;
import cn.superdesk.uniorder.service.organisation.SysEnterpriseService;
import cn.superdesk.uniorder.service.setting.UnifiedServiceService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 订单
 * @Author: linjinyu
 * @CreateDate: 2020/10/27 下午4:28
 * @UpdateUser: linjinyu
 * @UpdateDate: 2020/10/27 下午4:28
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Slf4j
@Service
public class UnifiedOrderServiceImpl implements UnifiedOrderService {


    @Autowired
    private UnifiedOrderMapper                   unifiedOrderMapper;
    @Autowired
    private UnifiedOrderMapperEx                 unifiedOrderMapperEx;
    @Autowired
    private UnifiedOrderMapperExCustomerDimOrder unifiedOrderMapperExCustomerDimOrder;
    @Autowired
    private UnifiedOrderMapperExCustomerDimGoods unifiedOrderMapperExCustomerDimGoods;
    @Autowired
    private UnifiedOrderMapperExSupplierDimOrder unifiedOrderMapperExSupplierDimOrder;
    @Autowired
    private UnifiedOrderMapperExSupplierDimGoods unifiedOrderMapperExSupplierDimGoods;

    @Autowired
    private AccountingUnifiedCustomerOrderService  accountingUnifiedCustomerOrderService;
    @Autowired
    private AccountingUnifiedSupplierXGoodsService accountingUnifiedSupplierXGoodsService;

    @Autowired
    private UnifiedOrderGoodsMapper   unifiedOrderGoodsMapper;
    @Autowired
    private UnifiedOrderGoodsMapperEx unifiedOrderGoodsMapperEx;
    @Autowired
    private UnifiedOrderGoodsService  unifiedOrderGoodsService;

    @Autowired
    private CommonOrderProcessService            commonOrderProcessService;
    @Autowired
    private CommonMergeOrderGoodsProcessService  commonOrderGoodsMergeProcessService;
    @Autowired
    private CommonMergeOrderCreditProcessService commonOrderCreditMergeProcessService;


    /****************************************** 退单部分 ******************************************/
    @Autowired
    private UnifiedOrderReturnMapper        unifiedOrderReturnMapper;
    @Autowired
    private UnifiedOrderReturnMapperEx      unifiedOrderReturnMapperEx;
    @Autowired
    private UnifiedOrderReturnGoodsMapper   unifiedOrderReturnGoodsMapper;
    @Autowired
    private UnifiedOrderReturnGoodsMapperEx unifiedOrderReturnGoodsMapperEx;
    /****************************************** 退单部分 ******************************************/


    /****************************************** 楼闪送专用 目前是这样 20200706 ******************************************/

    @Autowired
    private UnifiedOrderUpdateMapper   unifiedOrderUpdateMapper;
    @Autowired
    private UnifiedOrderUpdateMapperEx unifiedOrderUpdateMapperEx;

    /****************************************** 楼闪送专用 目前是这样 20200706 ******************************************/


    /****************************************** 分润部分 ******************************************/

    @Autowired
    private UnifiedOrderProfitMapper         unifiedOrderProfitMapper;
    @Autowired
    private UnifiedOrderProfitMapperEx       unifiedOrderProfitMapperEx;
    @Autowired
    private UnifiedChannelProfitSyncMapper   unifiedChannelProfitSyncMapper;
    @Autowired
    private UnifiedChannelProfitSyncMapperEx unifiedChannelProfitSyncMapperEx;

    /****************************************** 分润部分 ******************************************/

    /****************************************** 开票申请 发票 start ******************************************/

    @Autowired
    private InvoiceApplyCustomerService invoiceApplyService;

    /****************************************** 开票申请 发票 start ******************************************/


    @Autowired
    private SysEnterpriseService sysEnterpriseService;

    @Autowired
    private UnifiedServiceService unifiedServiceService;


    @Autowired
    private CommonEventPublisher commonEventPublisher;


    @Override
    public int insertSelective(UnifiedOrder t) {
        return unifiedOrderMapper.insertSelective(t);

    }

    @Override
    public int updateByPrimaryKeySelective(UnifiedOrder t) {

        return unifiedOrderMapper.updateByPrimaryKeySelective(t);
    }

    @Override
    public void deleteObj(Long id) {


    }

    @Override
    public UnifiedOrder findById(Long id) {

        return unifiedOrderMapper.selectByPrimaryKey(id);
    }


    @Override
    public List<UnifiedOrder> findAll(Map<String, Object> queryMap) {

        return unifiedOrderMapperEx.findAll(queryMap);
    }

    @Override
    public PageInfo<UnifiedOrder> findByPaging(Map<String, Object> params, Integer pageNo, Integer pageSize) {

        return null;
    }

    @Override
    public List<SelectOptionDepartment> getSelectPurchaseDepartment(SelectOptionDepartmentCriteria criteria, LoginSysUser loginSysUser) {

        PageHelper.startPage(criteria.getPageNumber(), criteria.getPageSize());

        List<SelectOptionDepartment> resultList = unifiedOrderMapperEx.getSelectPurchaseDepartment(criteria);

        PageHelper.clearPage();

        return resultList;
    }


    @Override
    public Integer countAll(Map<String, Object> queryMap) {
        return unifiedOrderMapperEx.countAll(queryMap);
    }

    /**
     * 新增 统一订单 好像只有楼闪送在用
     *
     * @param unifiedOrder
     * @param unifiedOrderGoodsList
     * @return
     */
    @Transactional
    @Override
    public UnifiedOrder addObjTran(UnifiedOrder unifiedOrder, List<UnifiedOrderGoods> unifiedOrderGoodsList) {

        unifiedOrderMapper.insert(unifiedOrder);

        for (UnifiedOrderGoods unifiedOrderGoods : unifiedOrderGoodsList) {
            unifiedOrderGoodsMapper.insert(unifiedOrderGoods);
        }


        // TODO mark by linjinyu 重构 分润 start =================================

        commonEventPublisher.triggerUnifiedOrderProfitCalculationEvent(unifiedOrder);

        // 1209 -- 计算分润
//		Map<String, Object> profitQuery = new HashMap<>();
//
//		profitQuery.put("projectId", unifiedOrder.getProjectId());
//		profitQuery.put("serviceNo", unifiedOrder.getServiceNo());
//
//		List<UnifiedChannelProfitSync> channelProfitSyncs = unifiedChannelProfitSyncMapperEx.findAll(profitQuery);
//
//		if (channelProfitSyncs != null && channelProfitSyncs.size() > 0) {
//
//			// 插入分润表
//			UnifiedChannelProfitSync channelProfitSync = channelProfitSyncs.get(0);
//
//			UnifiedOrderProfit profit = new UnifiedOrderProfit();
//
//			profit.setBusinessCode(channelProfitSync.getBusinessCode());
//			profit.setChannelId(channelProfitSync.getChannelId());
//			profit.setCreateTime(DateUtil.date());
//			profit.setOrgId(channelProfitSync.getOrganizationId());
//
//			profit.setProfitAmount(new BigDecimal(unifiedOrder.getAmount().doubleValue() * channelProfitSync.getProportion().doubleValue() / 100));
//			profit.setProportion(channelProfitSync.getProportion());
//
//			profit.setOrderSn(unifiedOrder.getSn());
//
//			UnifiedOrderProfit unifiedOrderProfit = unifiedOrderProfitMapper.selectBySn(unifiedOrder.getSn());
//
//			if (unifiedOrderProfit != null) {
//				profit.setId(unifiedOrderProfit.getId());
//				unifiedOrderProfitMapper.updateByPrimaryKeySelective(profit);
//			} else {
//				unifiedOrderProfitMapper.insert(profit);
//			}
//		}

        // TODO mark by linjinyu 重构 分润  end  =================================


        return unifiedOrder;
    }

    /**
     * 单主体情况
     * 根据 orderSn 得出 订单 entity (此订单包含正负的商品)
     * <p>
     * 双主体情况
     * (假定是正单号) 根据 orderSn 得出 正订单 entity
     * (假定是退单号) 根据 orderSn 得出 退订单 entity
     *
     * @param orderSn
     * @return
     */
    @Override
    public UnifiedOrder findByOrderSn(String orderSn) {

        return unifiedOrderMapperEx.findByOrderSn(orderSn);
    }

    /**
     * 单主体情况
     * 得不出
     * <p>
     * 双主体情况
     * 根据 正单 orderSn 找 订单表.refund_order_sn 字段 得出 退单List
     * 根据 退单 orderSn 找 订单表.refund_order_sn 字段 得出 正单List
     *
     * @param refundOrderSn
     * @return
     */
    @Override
    public List<UnifiedOrder> findByRefundOrderSn(String refundOrderSn) {

        if (StrUtil.isBlank(refundOrderSn)) {
            return null;
        }

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

//        UnifiedOrderExample example = new UnifiedOrderExample();
//        UnifiedOrderExample.Criteria criteria= example.createCriteria();
//        criteria.or

        return unifiedOrderMapperEx.findByRefundOrderSn(refundOrderSn);

    }

    public List<UnifiedOrder> findByRefundOrderSnAndSaleId(String orderSn, Long saleId) {

        if (StrUtil.isBlank(orderSn)) {
            return null;
        }

        if (ObjectUtil.isNull(saleId)) {
            return null;
        }

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

        UnifiedOrderExample          example  = new UnifiedOrderExample();
        UnifiedOrderExample.Criteria criteria = example.createCriteria();
        criteria
                .andRefundOrderSnEqualTo(orderSn)
                .andSaleIdEqualTo(saleId);

        resultList = unifiedOrderMapper.selectByExample(example);

        return resultList;
    }

    @Override
    public UnifiedOrder findByJdOrderSn(String jdOrderSn) {

        if (StrUtil.isBlank(jdOrderSn)) {
            return null;
        }

        return unifiedOrderMapperEx.findByJdOrderSn(jdOrderSn);
    }

    @Override
    public UnifiedOrder findByJdOrderSnAndSaleId(String jdOrderSn, Long saleId) {

        if (StrUtil.isBlank(jdOrderSn)) {
            return null;
        }

        if (ObjectUtil.isNull(saleId)) {
            return null;
        }

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

        UnifiedOrderExample          example  = new UnifiedOrderExample();
        UnifiedOrderExample.Criteria criteria = example.createCriteria();
        criteria
                .andExpressSnEqualTo(jdOrderSn)
                .andSaleIdEqualTo(saleId);

        resultList = unifiedOrderMapper.selectByExample(example);

        if (CollUtil.isNotEmpty(resultList)) {
            return resultList.get(0);
        } else {
            return null;
        }
    }


    /****************************************** 供应商结算 dim order 未对账 订单 start ******************************************/

    @Override
    public UnifiedOrderSupplierHeadSumVo getSupplierUnAccountingDimOrderHeadSum(Map<String, Object> params) {

        return unifiedOrderMapperExSupplierDimOrder.getSupplierUnAccountingDimOrderHeadSum(params);
    }

    @Override
    public List<UnifiedOrderSupplierDimOrderNotCheckVo> getSupplierUnAccountingDimOrderList(Map<String, Object> params) {

        return unifiedOrderMapperExSupplierDimOrder.getSupplierUnAccountingDimOrderList(params);
    }

    @Override
    public R<List<UnifiedOrderSupplierDimOrderNotCheckVo>> getSupplierUnAccountingDimOrderList(Map<String, Object> params, int pageNo, int pageSize) {

        PageHelper.startPage(pageNo, pageSize);
        List<UnifiedOrderSupplierDimOrderNotCheckVo>     resultList = unifiedOrderMapperExSupplierDimOrder.getSupplierUnAccountingDimOrderList(params);
        PageInfo<UnifiedOrderSupplierDimOrderNotCheckVo> page       = new PageInfo<UnifiedOrderSupplierDimOrderNotCheckVo>(resultList);
        PageHelper.clearPage();

        return new R<List<UnifiedOrderSupplierDimOrderNotCheckVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);

    }

    @Override
    public List<UnifiedOrderSupplierNotCheckDetail2GoodsVo> getSupplierUnAccountingDetail2Goods(Map<String, Object> params) {

        log.info("\n\n\n\ngetSupplierUnAccountDataGoods params \n{}\n\n\n\n", AnJsonUtils.toJson(params));

        return unifiedOrderMapperExSupplierDimOrder.getSupplierUnAccountingDetail2Goods(params);
    }

    /****************************************** 供应商结算 dim order 未对账 订单   end ******************************************/


    /****************************************** 供应商结算 dim goods 未对账 商品 start ******************************************/

    @Override
    public UnifiedOrderSupplierHeadSumVo getSupplierUnAccountingDimGoodsHeadSum(AccountingSupplierNotYetDimGoodsQueryCriteria criteria) {

        return unifiedOrderMapperExSupplierDimGoods.getSupplierUnAccountingDimGoodsHeadSum(criteria);
    }

    /**
     * 已添加 数据脱敏逻辑 20211203
     *
     * @param criteria
     * @param loginSysUser
     * @return
     */
    @Override
    public List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> getSupplierUnAccountingDimGoodsList(AccountingSupplierNotYetDimGoodsQueryCriteria criteria, LoginSysUser loginSysUser) {

        List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> resultList = unifiedOrderMapperExSupplierDimGoods.getSupplierUnAccountingDimGoodsList(criteria);

        /**
         * 数据脱敏
         * 1. 按登陆类型
         * 2. 按开关 SensitiveRequireSwitchEnum SensitiveRequireSwitchConstants.SWITCH_PARAM 开关目前有两种 TODO 有空再写个方法统一判定
         */
        if ((ObjectUtil.isNotNull(loginSysUser)
                && ObjectUtil.isNotNull(loginSysUser.getOutLogin())
                && loginSysUser.getOutLogin().compareTo(SysLoginTypeEnum.福利商城_侨城汇.getKey()) == 0)
                || criteria.getSensitiveRequireSwitch().compareTo(SensitiveRequireSwitchEnum.On.getKey()) == 0) {
            DesensitizedUtils.desensitization(resultList);
        }

        additionalInfoUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        DtoSugarUpUtils.sugarUpUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        return resultList;
    }

    /**
     * #供应商->未对账商品#
     * #供应商->对账单->详情#
     *
     * @param resultList
     */
    private void additionalInfoUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(
            List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> resultList) {

        if (CollUtil.isEmpty(resultList)) {
            return;
        }

        UnifiedServiceCacheStruct unifiedServiceCacheStruct = unifiedServiceService.convertForMapAsOrderType();

        for (UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo vo : resultList) {

            // 补 订单类型-订单来源-引用enum CommonServiceNoEnum
//            if (ObjectUtil.isNotNull(vo.getServiceNo())) {
//                vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
//            } else {
//                vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
//            }

            vo.setServiceNoName(unifiedServiceCacheStruct.lookUpServiceNo(vo.getServiceNo()));
//            vo.setOrderStateName(unifiedServiceCacheStruct.lookUpOrderState(vo.getServiceNo(), vo.getOrderState()));
//            vo.setPayTypeName(unifiedServiceCacheStruct.lookUpPayType(vo.getServiceNo(), vo.getPayType()));
//            vo.setPayStateName()
        }

    }

    @Override
    public R<List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo>> getSupplierUnAccountingDimGoodsListByPageQuery(
            AccountingSupplierNotYetDimGoodsQueryCriteria queryCriteria,
            LoginSysUser loginSysUser) {

        PageHelper.startPage(queryCriteria.getPageNumber(), queryCriteria.getPageSize());
        List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo>     resultList = unifiedOrderMapperExSupplierDimGoods.getSupplierUnAccountingDimGoodsList(queryCriteria);
        PageInfo<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> pageInfo   = new PageInfo<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo>(resultList);
        PageHelper.clearPage();

        /**
         * 数据脱敏
         * 1. 按登陆类型
         * 2. 按开关 SensitiveRequireSwitchEnum SensitiveRequireSwitchConstants.SWITCH_PARAM 开关目前有两种 TODO 有空再写个方法统一判定
         */
        if ((ObjectUtil.isNotNull(loginSysUser)
                && ObjectUtil.isNotNull(loginSysUser.getOutLogin())
                && loginSysUser.getOutLogin().compareTo(SysLoginTypeEnum.福利商城_侨城汇.getKey()) == 0)
                || queryCriteria.getSensitiveRequireSwitch().compareTo(SensitiveRequireSwitchEnum.On.getKey()) == 0) {
            DesensitizedUtils.desensitization(resultList);
        }

        additionalInfoUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        DtoSugarUpUtils.sugarUpUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        return new R<List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo>>(pageInfo.getPageNum(), pageInfo.getPageSize(), (int) pageInfo.getTotal(), resultList);

    }
    /****************************************** 供应商结算 dim goods 未对账 商品   end ******************************************/

    /****************************************** 供应商结算 对账单详情 start ******************************************/

    /**
     * 已添加 数据脱敏逻辑 20211203
     *
     * @param queryCriteria
     * @param loginSysUser
     * @return
     */
    @Override
    public List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> getSupplierStatementOfAccountDetailDimOrder2Goods(
            SuplierStatementOfAccountDetailQueryCriteria queryCriteria,
            LoginSysUser loginSysUser) {

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


        Map<String, Object> queryParams = new HashMap<>();
        queryParams.put("accountingOrderSn", queryCriteria.getAccountingOrderSn());

        resultList = unifiedOrderGoodsMapperEx.getSupplierStatementOfAccountDetailDimOrder2Goods(queryParams);

        /**
         * 数据脱敏
         * 1. 按登陆类型
         * 2. 按开关 SensitiveRequireSwitchEnum SensitiveRequireSwitchConstants.SWITCH_PARAM 开关目前有两种 TODO 有空再写个方法统一判定
         */
        if ((ObjectUtil.isNotNull(loginSysUser)
                && ObjectUtil.isNotNull(loginSysUser.getOutLogin())
                && loginSysUser.getOutLogin().compareTo(SysLoginTypeEnum.福利商城_侨城汇.getKey()) == 0)
                || queryCriteria.getSensitiveRequireSwitch().compareTo(SensitiveRequireSwitchEnum.On.getKey()) == 0) {
            DesensitizedUtils.desensitization(resultList);
        }

        additionalInfoUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        DtoSugarUpUtils.sugarUpUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);

        return resultList;
    }

    /**
     * 已添加 数据脱敏逻辑 20211203
     *
     * @param accountingOrderSn
     * @param loginSysUser
     * @return
     */
    @Override
    public List<UnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo> getSupplierStatementOfAccountDetailDimGoods2Goods(
            String accountingOrderSn,
            LoginSysUser loginSysUser) {

        log.info("供应商结算 对账单详情 getSupplierStatementOfAccountDetailDimGoods2Goods {}", accountingOrderSn);

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

        if (StringUtils.isBlank(accountingOrderSn)) {
            return resultList;
        }

        List<AccountingUnifiedSupplierXGoods> statementOfAccountXGoods = accountingUnifiedSupplierXGoodsService.findByAccountingOrderSn(accountingOrderSn);

        List<Long> processSysUnifiedOrderGoodsIds = new ArrayList<>();

        processSysUnifiedOrderGoodsIds = statementOfAccountXGoods.stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getUnifiedOrderGoodsId()))
                .map(AccountingUnifiedSupplierXGoods::getUnifiedOrderGoodsId)
                .collect(Collectors.toList());

        if (CollUtil.isNotEmpty(processSysUnifiedOrderGoodsIds)) {

            AccountingSupplierNotYetDimGoodsQueryCriteria criteria = new AccountingSupplierNotYetDimGoodsQueryCriteria();
            criteria.setUnifiedOrderGoodsIds(processSysUnifiedOrderGoodsIds);

            // 已添加 数据脱敏逻辑 20211203
            resultList = getSupplierUnAccountingDimGoodsList(criteria, loginSysUser);
        } else {
            additionalInfoUnifiedOrderJoinGoodsOfSupplierStatementOfAccountVo(resultList);
        }


        return resultList;

    }
    /****************************************** 供应商结算 对账单详情   end ******************************************/


    /****************************************** 关于 供应商结算 对账单 设置 对账状态 或 恢复 对账状态 start ******************************************/

    @Override
    public int updateAccountingStateSupplierBySysUnifiedOrderIds(List<Long> sysUnifiedOrderIds, CommonAccountingStateEnum state) {

//        弃用 20201029
//        Map<String, Object> forUpdateOrderAccountingStateparams = new HashMap<>();
//        forUpdateOrderAccountingStateparams.put("ids", sysUnifiedOrderIds);// ids.split(",")
//        // 更新 订单 对账状态 update unified_order set accounting_state_supplier = 1 UnifiedOrderAccountingState.已对账.getKey() where id in (ids)
//        // 已对账(1, "已对账"),
//        // 未对账(2, "未对账"),
//        // 已作废(3, "已作废"),// 20200713 添加 by linjinyu 原因 老是说要作废什么订单
//        unifiedOrderMapperExSupplierDimOrder.updateAccountingStateSupplier(forUpdateOrderAccountingStateparams);

        if (CollUtil.isEmpty(sysUnifiedOrderIds)) {
            log.error("updateAccountingStateSupplierBySysUnifiedOrderIds sysUnifiedOrderIds isEmpty = true");
            return 0;
        }

        UnifiedOrderExample forUpdateAccountingStateOrderExample = new UnifiedOrderExample();
        forUpdateAccountingStateOrderExample.createCriteria()
                .andIdIn(sysUnifiedOrderIds);

        UnifiedOrder forUpdateAccountingStateOrderEntity = new UnifiedOrder();
        forUpdateAccountingStateOrderEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderMapper.updateByExampleSelective(
                forUpdateAccountingStateOrderEntity,
                forUpdateAccountingStateOrderExample
        );
    }

    @Override
    public int updateAccountingStateSupplierByOrderSns(List<String> orderSns, CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(orderSns)) {
            log.error("updateAccountingStateSupplierBySysUnifiedOrderIds sysUnifiedOrderIds isEmpty = true");
            return 0;
        }

        UnifiedOrderExample forUpdateAccountingStateOrderExample = new UnifiedOrderExample();
        forUpdateAccountingStateOrderExample.createCriteria()
                .andOrderSnIn(orderSns);

        UnifiedOrder forUpdateAccountingStateOrderEntity = new UnifiedOrder();
        forUpdateAccountingStateOrderEntity.setAccountingStateSupplier(state.getKey());

        return unifiedOrderMapper.updateByExampleSelective(
                forUpdateAccountingStateOrderEntity,
                forUpdateAccountingStateOrderExample
        );
    }

    /****************************************** 关于 供应商结算 对账单 设置 对账状态 或 恢复 对账状态   end ******************************************/


    /****************************************** 关于 客户结算 对账单 设置 对账状态 或 恢复 对账状态 start ******************************************/
    /**
     * 更新 字段 对账状态 By List<Long> sysUnifiedOrderIds
     * 不对账(-1, "不对账"),
     * 已对账(1, "已对账"),
     * 未对账(2, "未对账"),
     * 已作废(3, "已作废"),
     *
     * @param sysUnifiedOrderIds
     * @param state
     */
    @Override
    public void updateAccountingStateCustomerBySysUnifiedOrderIds(
            List<Long> sysUnifiedOrderIds,
            CommonAccountingStateEnum state) {


        if (CollUtil.isEmpty(sysUnifiedOrderIds)) {
            log.error("updateAccountingStateCustomerBySysUnifiedOrderIds sysUnifiedOrderIds isEmpty = true");
            return;
        }

        UnifiedOrderExample forUpdateAccountingStateOrderExample = new UnifiedOrderExample();
        forUpdateAccountingStateOrderExample.createCriteria()
                .andIdIn(sysUnifiedOrderIds);

        UnifiedOrder forUpdateAccountingStateOrderEntity = new UnifiedOrder();
        forUpdateAccountingStateOrderEntity.setAccountingStateCustomer(state.getKey());

        unifiedOrderMapper.updateByExampleSelective(forUpdateAccountingStateOrderEntity, forUpdateAccountingStateOrderExample);
    }

    /**
     * 更新 字段 对账状态 By List<String> orderSns
     * 不对账(-1, "不对账"),
     * 已对账(1, "已对账"),
     * 未对账(2, "未对账"),
     * 已作废(3, "已作废"),
     *
     * @param orderSns
     * @param state
     */
    @Override
    public void updateAccountingStateCustomerByOrderSns(
            List<String> orderSns,
            CommonAccountingStateEnum state) {

        if (CollUtil.isEmpty(orderSns)) {
            log.error("updateAccountingStateSupplierBySysUnifiedOrderIds sysUnifiedOrderIds isEmpty = true");
            return;
        }

        UnifiedOrderExample forUpdateAccountingStateOrderExample = new UnifiedOrderExample();
        forUpdateAccountingStateOrderExample.createCriteria()
                .andOrderSnIn(orderSns);

        UnifiedOrder forUpdateAccountingStateOrderEntity = new UnifiedOrder();
        forUpdateAccountingStateOrderEntity.setAccountingStateCustomer(state.getKey());

        unifiedOrderMapper.updateByExampleSelective(forUpdateAccountingStateOrderEntity, forUpdateAccountingStateOrderExample);
    }

    /****************************************** 关于 客户结算 对账单 设置 对账状态 或 恢复 对账状态   end ******************************************/

    /****************************************** 订单 状态 回款状态 start ******************************************/
    @Override
    public void updateFieldBackAccountStatusByInvoiceX(List<InvoiceApplyXGoods> invoiceX) {

        // 需证明
        // accounting_order_type=1 dim_create_by=0 代表 accounting_unified_customer_order.id (accounting_unified_customer_order_goods.id|unified_order_goods.id)
        // 不必证明
        // accounting_order_type=1 dim_create_by=1 代表 unified_order.id unified_order_goods.id
        // accounting_order_type=2 dim_create_by=2 代表 unified_order.id unified_order_goods.id

        // 先要得出到底是什么情况(上边的情况之一),如果存大多种情况,这个就不能处理了
        Map<String, List<InvoiceApplyXGoods>> transferMapGroupByAccountingOrderTypeAndDimCreateBy = invoiceX.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByAccountingOrderTypeAndDimCreateBy(e), Collectors.toList()));

        Integer typeCount = transferMapGroupByAccountingOrderTypeAndDimCreateBy.size();

        if (typeCount.compareTo(1) > 0) {
            log.error("updateFieldBackAccountStatusByInvoiceX 先要得出到底是什么情况(上边的情况之一),如果存大多种情况,这个就不能处理了");
            return;
        }

        /****************************************** 得出类型 start ******************************************/

        String[] c = new String[0];
        String   type;
        transferMapGroupByAccountingOrderTypeAndDimCreateBy.keySet().toArray(c);
        type = c[0];

        /****************************************** 得出回款状态 start ******************************************/
        Map<Long, List<InvoiceApplyXGoods>> transferMapGroupByUnknowOrderId = invoiceX.parallelStream()
                .collect(Collectors.groupingBy(e -> fetchGroupKeyByUnknowOrderId(e), Collectors.toList()));

        // 每份订单的数据 Key unKnowOrderId -> List<InvoiceOrder>
        for (Map.Entry<Long, List<InvoiceApplyXGoods>> _entry : transferMapGroupByUnknowOrderId.entrySet()) {

            log.info("正在处理的类型为 : {}", type);

            Long unifiedOrderId = 0L;
            switch (type) {
                case "1_0":

                    // 转换 accounting_unified_customer_order.id -> unifiedOrderId
                    AccountingUnifiedCustomerOrder accountingUnifiedCustomerOrder = accountingUnifiedCustomerOrderService.findAccountingUnifiedCustomerOrderById(_entry.getKey());
                    unifiedOrderId = accountingUnifiedCustomerOrder.getOrderId();
                    break;
                case "1_1":
                    unifiedOrderId = _entry.getKey();
                    break;
                case "2_2":
                    unifiedOrderId = _entry.getKey();
                    break;
                default:
                    break;
            }
            Integer _invoiceXCount                = _entry.getValue().size();
            Integer _invoiceXBackAccountStatusEq1 = AnIntegerUtils.getInteger(_entry.getValue().stream().filter(o -> null != o.getBackStatus() && o.getBackStatus().equals(1)).count());


            int ret = updateFieldBackAccountStatusByCheckRatio(_invoiceXCount, _invoiceXBackAccountStatusEq1, unifiedOrderId);

        }


    }

    /**
     * 更新 字段 是否回款的问题 判定
     *
     * @param fullCount
     * @param seizeCount
     * @param unifiedOrderId
     * @return
     */
    public int updateFieldBackAccountStatusByCheckRatio(Integer fullCount, Integer seizeCount, Long unifiedOrderId) {

        // return 为 ret 标记 不是计算数量
        if (fullCount.compareTo(0) <= 0) {
            return 0;
        }

        if (seizeCount.compareTo(0) <= 0) {
            return 0;
        }

        UnifiedOrderBackStatusEnum unifiedOrderBackStatusEnum;
        if (fullCount.compareTo(seizeCount) == 0) {
            unifiedOrderBackStatusEnum = UnifiedOrderBackStatusEnum.全部回款;
        } else {
            unifiedOrderBackStatusEnum = UnifiedOrderBackStatusEnum.部分回款;
        }

        return updateFieldBackAccountStatusByUnifiedOrderId(unifiedOrderId, unifiedOrderBackStatusEnum);

    }

    /**
     * 更新 字段 是否回款的问题
     *
     * @param unifiedOrderId
     * @param unifiedOrderBackStatusEnum
     * @return
     */
    public int updateFieldBackAccountStatusByUnifiedOrderId(
            Long unifiedOrderId,
            UnifiedOrderBackStatusEnum unifiedOrderBackStatusEnum) {

        UnifiedOrder unifiedOrder = new UnifiedOrder();
        unifiedOrder.setId(unifiedOrderId);
        unifiedOrder.setBackAccountStatus(unifiedOrderBackStatusEnum.getKey());

        return unifiedOrderMapper.updateByPrimaryKeySelective(unifiedOrder);
    }


    /**
     * 私有方法 用于分组
     *
     * @param invoiceOrder
     * @return
     */
    private String fetchGroupKeyByAccountingOrderTypeAndDimCreateBy(InvoiceApplyXGoods invoiceOrder) {
        return invoiceOrder.getAccountingOrderType() + "_" + invoiceOrder.getDimCreateBy();
    }

    /**
     * 私有方法 用于分组
     *
     * @param invoiceOrder
     * @return
     */
    private Long fetchGroupKeyByUnknowOrderId(InvoiceApplyXGoods invoiceOrder) {
        return invoiceOrder.getAccountingOrderId();
    }
    /****************************************** 订单 状态 回款状态   end ******************************************/


    /****************************************** 客户结算 dim order 未对账 订单 start ******************************************/
    @Override
    public UnifiedOrderCommonHeadSum getCustomerUnAccountingDimOrderHeadSum(Map<String, Object> params) {

        return unifiedOrderMapperExCustomerDimOrder.getCustomerUnAccountingDimOrderHeadSum(params);
    }

    @Override
    public List<UnifiedOrderCustomerNotCheckVo> getCustomerUnAccountingDimOrderList(Map<String, Object> params) {
        return unifiedOrderMapperExCustomerDimOrder.getCustomerUnAccountingDimOrderList(params);
    }

    @Override
    public R<List<UnifiedOrderCustomerNotCheckVo>> getCustomerUnAccountingDimOrderList(Map<String, Object> params, int pageNo, int pageSize) {

        log.info("getCustomerUnAccountingDimOrderList : {}", AnJsonUtils.toJson(params));

        PageHelper.startPage(pageNo, pageSize);
        List<UnifiedOrderCustomerNotCheckVo>     result = unifiedOrderMapperExCustomerDimOrder.getCustomerUnAccountingDimOrderList(params);
        PageInfo<UnifiedOrderCustomerNotCheckVo> page   = new PageInfo<UnifiedOrderCustomerNotCheckVo>(result);
        PageHelper.clearPage();

        return new R<List<UnifiedOrderCustomerNotCheckVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), result);
    }

    /****************************************** 客户结算 dim order 未对账 订单   end ******************************************/

    /****************************************** 客户结算 dim goods 未对账 商品 start ******************************************/

    @Override
    public UnifiedOrderCustomerHeadSumVo getCustomerUnAccountingDimGoodsHeadSum(Map<String, Object> params, LoginSysUser loginSysUser) {
        return unifiedOrderMapperExCustomerDimGoods.getCustomerUnAccountingDimGoodsHeadSum(params);
    }

    @Override
    public List<CustomerUnAccountingDimGoodsVo> getCustomerUnAccountingDimGoodsList(Map<String, Object> params, LoginSysUser loginSysUser) {

        List<CustomerUnAccountingDimGoodsVo> resultList = unifiedOrderMapperExCustomerDimGoods.getCustomerUnAccountingDimGoodsList(params);

        additionalInfoGetCustomerUnAccountingDimGoodsList(resultList);

        return resultList;
    }

    @Override
    public R<List<CustomerUnAccountingDimGoodsVo>> getCustomerUnAccountingDimGoodsList(Map<String, Object> params, int pageNo, int pageSize, LoginSysUser loginSysUser) {

        log.info("传入参数 {}", AnJsonUtils.toJson(params));

        PageHelper.startPage(pageNo, pageSize);
        List<CustomerUnAccountingDimGoodsVo>     resultList = unifiedOrderMapperExCustomerDimGoods.getCustomerUnAccountingDimGoodsList(params);
        PageInfo<CustomerUnAccountingDimGoodsVo> page       = new PageInfo<CustomerUnAccountingDimGoodsVo>(resultList);
        PageHelper.clearPage();

        additionalInfoGetCustomerUnAccountingDimGoodsList(resultList);

        return new R<List<CustomerUnAccountingDimGoodsVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);
    }

    /**
     * #客户结算->未对账商品#
     *
     * @param resultList
     */
    private void additionalInfoGetCustomerUnAccountingDimGoodsList(List<CustomerUnAccountingDimGoodsVo> resultList) {

        if (CollUtil.isEmpty(resultList)) {
            return;
        }

        UnifiedServiceCacheStruct unifiedServiceCacheStruct = unifiedServiceService.convertForMapAsOrderType();

        for (CustomerUnAccountingDimGoodsVo vo : resultList) {

//            if (ObjectUtil.isNotNull(vo.getServiceNo())) {
//                vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
//            } else {
//                vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
//            }

            // 商品别名 mark by linjinyu at 20210520
            if (StringUtils.isNotBlank(vo.getGoodsAlias())) {
                vo.setGoodsName(vo.getGoodsName() + "(" + vo.getGoodsAlias() + ")");
            }

            vo.setGoodsAmount(new BigDecimal(vo.getPrice().doubleValue() * vo.getQuantity()));
            vo.setGoodsCostAmount(new BigDecimal(vo.getCostPrice().doubleValue() * vo.getQuantity()));

            /****************************************  start ****************************************/

            vo.setServiceNoName(unifiedServiceCacheStruct.lookUpServiceNo(vo.getServiceNo()));
//            vo.setOrderStateName(unifiedServiceCacheStruct.lookUpOrderState(vo.getServiceNo(), vo.getOrderState()));
//            vo.setPayTypeName(unifiedServiceCacheStruct.lookUpPayType(vo.getServiceNo(), vo.getPayType()));
//            vo.setPayStateName()

        }
    }

    /****************************************** 客户结算 dim goods 未对账 商品   end ******************************************/


    /****************************************** 订单管理 start ******************************************/
    @Override
    public UnifiedOrderCommonHeadSum getOrderManagerGoodsPageHead(Map<String, Object> params) {

        return unifiedOrderMapperEx.getOrderManagerGoodsPageHead(params);
    }

    @Override
    public R<List<UnifiedOrderGoodsVo>> getOrderManagerGoodsByPage(Map<String, Object> params, int pageNo, int pageSize) {

        PageHelper.startPage(pageNo, pageSize);
        List<UnifiedOrderGoodsVo>     resultList = unifiedOrderMapperEx.getOrderManagerGoodsView(params);
        PageInfo<UnifiedOrderGoodsVo> page       = new PageInfo<UnifiedOrderGoodsVo>(resultList);
        PageHelper.clearPage();

        additionalInfoGetOrderManagerGoodsView(resultList);

        return new R<List<UnifiedOrderGoodsVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), resultList);
    }

    /**
     * Excel导出 取数据
     * 1. 导出报表
     * 2. 导出成本
     *
     * @param params
     * @return
     */
    @Override
    public List<UnifiedOrderGoodsVo> getOrderManagerGoodsView(Map<String, Object> params) {

        /****************************************** 数据加工 本来在controller层 mark by linjinyu at 20210305 重构 start ******************************************/

        List<UnifiedOrderGoodsVo> resultList = unifiedOrderMapperEx.getOrderManagerGoodsView(params);

        // 附加程序 mark by linjinyu at 20210305 重构
        additionalInfoGetOrderManagerGoodsView(resultList);

        /****************************************** 数据加工 本来在controller层 mark by linjinyu at 20210305 重构 start ******************************************/

        return resultList;
    }


    /**
     * #订单管理->订单管理#
     * OrderManagerGoodsView 附加程序 mark by linjinyu at 20210305 重构
     *
     * @param resultList
     */
    private void additionalInfoGetOrderManagerGoodsView(List<UnifiedOrderGoodsVo> resultList) {

        if (CollUtil.isEmpty(resultList)) {
            return;
        }


        // 得出 order_sn 集合
        List<String> orderSnList = resultList
                .stream()
                .filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn()))
                .map(UnifiedOrderGoodsVo::getOrderSn)
                .collect(Collectors.toList());
        log.info("得出 orderSn 为 \n {}", AnJsonUtils.toJson(orderSnList));
        Map<String, InvoiceApply> orderSn2InvoiceApplyMap = invoiceApplyService.findInvoiceByOrderSnList(orderSnList);
        log.info("查出 applies 为  \n {}", AnJsonUtils.toJson(orderSn2InvoiceApplyMap));

        /****************************************  start ****************************************/

        UnifiedServiceCacheStruct unifiedServiceCacheStruct = unifiedServiceService.convertForMapAsOrderType();


        for (UnifiedOrderGoodsVo vo : resultList) {

//            // 补 订单类型-订单来源-引用enum CommonServiceNoEnum
//            if (ObjectUtil.isNotNull(vo.getServiceNo())) {
//                vo.setServiceNoName(CommonServiceNoEnum.getByServiceNo(vo.getServiceNo()).getServiceName());
//            } else {
//                vo.setServiceNoName(CommonServiceNoEnum.UNKNOW.getServiceName());
//            }

            // 商品别名 mark by linjinyu at 20210520
            if (StringUtils.isNotBlank(vo.getGoodsAlias())) {
                vo.setGoodsName(vo.getGoodsName() + "(" + vo.getGoodsAlias() + ")");
            }

            vo.setGoodsAmount(new BigDecimal(vo.getPrice().doubleValue() * vo.getQuantity()));
            vo.setGoodsCostAmount(new BigDecimal(vo.getCostPrice().doubleValue() * vo.getQuantity()));

            // 付款状态 TODO 统一订单不转换 直接 显示第三方过来的
//			vo.setPayStateName(UnifiedOrderMixPayAboutName.getPayStateName(viewUnifiedOrderGoods.getServiceNo(), viewUnifiedOrderGoods.getPayState()));
            // 支付方式 TODO 统一订单不转换 直接 显示第三方过来的
//			vo.setPayTypeName(UnifiedOrderMixPayAboutName.getPayTypeName(viewUnifiedOrderGoods.getServiceNo(), viewUnifiedOrderGoods.getPayType()));
            // 订单状态  TODO 统一订单不转换 直接 显示第三方过来的
//			vo.setOrderStateName();

            /****************************************  start ****************************************/

            vo.setServiceNoName(unifiedServiceCacheStruct.lookUpServiceNo(vo.getServiceNo()));
//            vo.setOrderStateName(unifiedServiceCacheStruct.lookUpOrderState(vo.getServiceNo(), vo.getOrderState()));
//            vo.setPayTypeName(unifiedServiceCacheStruct.lookUpPayType(vo.getServiceNo(), vo.getPayType()));
//            vo.setPayStateName()


            // 开票申请 发票状态
            vo.setInvoiceStatusName(UnifiedOrderInvoiceStateEnum.getDesc(vo.getInvoiceStatus()));

            // 开票申请
            if (null != orderSn2InvoiceApplyMap.get(vo.getOrderSn())) {

                InvoiceApply temp = orderSn2InvoiceApplyMap.get(vo.getOrderSn());

                log.info("订单号 : {} 查到了发票信息", AnJsonUtils.toJson(temp));

                vo.setInvoiceNumber(temp.getInvoiceNumber());
                vo.setInvoiceApplySn(temp.getInvoiceApplySn());
                vo.setInvApplyTime(temp.getApplyTime());
                vo.setInvMakeInvoiceTime(temp.getMakeInvoiceTime());

                vo.setInvoiceStatusName(UnifiedOrderInvoiceStateEnum.getDesc(temp.getInvoiceStatus()));
            } else {
                log.info("订单号 : {} 没查到发票信息?", vo.getOrderSn());
            }
        }
    }

    @Override
    public R<List<Org2VirtStatisticsVo>> getOrg2VirtStatistics(Map<String, Object> params, int pageNum, int pageSize) {


        List<Org2VirtStatisticsVo> result = new ArrayList<>();

        Long orgId  = AnLongUtils.getLong(params.get("projectId"));
        Long virtId = AnLongUtils.getLong(params.get("purchaseVirtId"));

        Integer mode = AnIntegerUtils.getInteger(params.get("mode"));

        List<Long> virtIds = new ArrayList<>();

        // 项目
        if (null != mode && mode.equals(1)) {

            PageHelper.startPage(pageNum, pageSize);

            // 清理 orgId virtId
            params.put("projectId", orgId);
            params.put("purchaseVirtId", null);

            result = unifiedOrderMapperEx.getOrg2VirtStatistics(params);

            PageInfo<Org2VirtStatisticsVo> page = new PageInfo<Org2VirtStatisticsVo>(result);
            PageHelper.clearPage();

            return new R<List<Org2VirtStatisticsVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), result);
        }
        // 企业
        else if (null != mode && mode.equals(2)) {

            PageHelper.startPage(pageNum, pageSize);

            // 清理 orgId virtId
            params.put("projectId", orgId);
            params.put("purchaseVirtId", virtId);

            result = unifiedOrderMapperEx.getOrg2VirtStatistics(params);

            PageInfo<Org2VirtStatisticsVo> page = new PageInfo<Org2VirtStatisticsVo>(result);
            PageHelper.clearPage();

            return new R<List<Org2VirtStatisticsVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), result);
        }
        // 指定 项目
        else if (null != orgId) {

            List<SelectOptionVirt> orgList = sysEnterpriseService.getVirtSelectByOutOrgId(orgId);

            PageHelper.startPage(pageNum, pageSize);
            if (CollUtil.isNotEmpty(orgList)) {

                virtIds = orgList.stream().filter(o -> o.getVirtId() != null).filter(AnLamdaUtils.distinctByKey(o -> o.getVirtId())).map(SelectOptionVirt::getVirtId).collect(Collectors.toList());

                log.info("outVirtIds # {} #", AnJsonUtils.toJson(virtIds.toArray()));
                params.put("outVirtIds", virtIds.toArray());
                result = unifiedOrderMapperEx.getOrg2VirtStatistics(params);
            }

            PageInfo<Org2VirtStatisticsVo> page = new PageInfo<Org2VirtStatisticsVo>(result);
            PageHelper.clearPage();

            return new R<List<Org2VirtStatisticsVo>>(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), result);
        }
        // 指定 企业
        else if (null != virtId) {

            virtIds.add(virtId);
            log.info("outVirtIds", AnJsonUtils.toJson(virtIds.toArray()));
            params.put("outVirtIds", virtIds.toArray());
            result = unifiedOrderMapperEx.getOrg2VirtStatistics(params);

            return new R<List<Org2VirtStatisticsVo>>(1, 1, 1, result);

        }

        //
        else {
            return new R<List<Org2VirtStatisticsVo>>(0, 0, 0, result);
        }

    }

    /****************************************** 订单管理   end ******************************************/

    @Override
    public BigDecimal getPayAmount(Map<String, Object> upaymap) {

        return unifiedOrderMapperEx.getPayAmount(upaymap);
    }

    @Override
    public BigDecimal getAmount(Map<String, Object> query) {

        return unifiedOrderMapperEx.getAmount(query);
    }

    @Override
    public List<WxBillOrder> getVirtOrder(Map<String, Object> params) {
        return unifiedOrderMapperEx.getVirtOrder(params);
    }

    @Override
    public List<UnifiedOrder> findByDzId(Map<String, Object> params) {
        return unifiedOrderMapperEx.findAll(params);
    }

    @Override
    public Integer getOrderCount(Map<String, Object> queryMap) {
        return unifiedOrderMapperEx.getOrderCount(queryMap);
    }


    /**
     * 统一订单's unified_order.id s
     *
     * @param sysUnifiedOrderIds
     * @return
     */
    @Override
    public List<UnifiedOrder> findBySysUnifiedOrderIds(List<Long> sysUnifiedOrderIds) {

        UnifiedOrderExample example = new UnifiedOrderExample();
        example.createCriteria()
                .andIdIn(sysUnifiedOrderIds);

        example.setOrderByClause("create_time ASC");

        List<UnifiedOrder> result = unifiedOrderMapper.selectByExample(example);
        return result;

    }

    @Override
    public List<UnifiedOrder> findByOrderSns(List<String> orderSns) {

        UnifiedOrderExample example = new UnifiedOrderExample();
        example.createCriteria()
                .andOrderSnIn(orderSns);
        List<UnifiedOrder> result = unifiedOrderMapper.selectByExample(example);
        return result;

    }


    /****************************************** 工具方法 sysUnifiedOrderIds 推导 start ******************************************/
    /**
     * 工具方法 统一订单's unified_order.id s
     *
     * @param sysUnifiedOrderIds
     * @return
     */
    @Override
    public List<String> convertSysUnifiedOrderIds2OrderSn(List<Long> sysUnifiedOrderIds) {

        List<String> result = new ArrayList<>();

        List<UnifiedOrder> unifiedOrderList = findBySysUnifiedOrderIds(sysUnifiedOrderIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream()
                    .filter(AnLamdaUtils.distinctByKey(o -> o.getOrderSn()))
                    .map(UnifiedOrder::getOrderSn)
                    .collect(Collectors.toList());
        }

        return result;

    }

    /**
     * 工具方法
     *
     * @param sysUnifiedOrderIds
     * @return
     */
    @Override
    public Map<Long, String> convertSysUnifiedOrderIds2MapSysUnifiedOrderId2OrderSn(List<Long> sysUnifiedOrderIds) {

        Map<Long, String> result = new HashMap<>();

        List<UnifiedOrder> unifiedOrderList = findBySysUnifiedOrderIds(sysUnifiedOrderIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream().collect(Collectors.toMap(UnifiedOrder::getId, UnifiedOrder::getOrderSn));
        }

        return result;

    }

    /**
     * 工具方法
     *
     * @param sysUnifiedOrderIds
     * @return
     */
    @Override
    public Map<Long, UnifiedOrder> convertSysUnifiedOrderIds2MapSysUnifiedOrderId2Entity(List<Long> sysUnifiedOrderIds) {

        Map<Long, UnifiedOrder> result = new HashMap<>();

        List<UnifiedOrder> unifiedOrderList = findBySysUnifiedOrderIds(sysUnifiedOrderIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream().collect(Collectors.toMap(UnifiedOrder::getId, v -> v, (k, v) -> v));
        }

        return result;

    }

    /**
     * 工具方法
     *
     * @param sysUnifiedOrderIds
     * @return
     */
    @Override
    public Map<String, UnifiedOrder> convertSysUnifiedOrderIds2MapOrderSn2Entity(List<Long> sysUnifiedOrderIds) {

        Map<String, UnifiedOrder> result = new HashMap<>();

        List<UnifiedOrder> unifiedOrderList = findBySysUnifiedOrderIds(sysUnifiedOrderIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream().collect(Collectors.toMap(UnifiedOrder::getOrderSn, v -> v, (k, v) -> v));
        }

        return result;

    }

    @Override
    public Map<String, Long> convertSysUnifiedOrderIds2MapOrderSn2SysUnifiedOrderId(List<Long> sysUnifiedOrderIds) {

        Map<String, Long> result = new HashMap<>();

        List<UnifiedOrder> unifiedOrderList = findBySysUnifiedOrderIds(sysUnifiedOrderIds);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream().collect(Collectors.toMap(UnifiedOrder::getOrderSn, UnifiedOrder::getId));
        }

        return result;
    }

    /****************************************** 工具方法 sysUnifiedOrderIds 推导   end ******************************************/


    /****************************************** 工具方法 orderSns 推导 start ******************************************/
    @Override
    public Map<String, Long> convertOrderSns2MapOrderSn2SysUnifiedOrderId(List<String> orderSns) {

        Map<String, Long> result = new HashMap<>();

        List<UnifiedOrder> unifiedOrderList = findByOrderSns(orderSns);

        if (CollUtil.isNotEmpty(unifiedOrderList)) {
            result = unifiedOrderList.stream().collect(Collectors.toMap(UnifiedOrder::getOrderSn, UnifiedOrder::getId));
        }

        return result;
    }

    @Override
    public void deleteUnifiedOrderBatch(List<String> processOrderSn) {
        UnifiedOrderExample unifiedOrderExample = new UnifiedOrderExample();
        unifiedOrderExample.createCriteria().andOrderSnIn(processOrderSn);
        unifiedOrderMapper.deleteByExample(unifiedOrderExample);
    }

    @Override
    public void deleteUnifiedOrderBatchByOrderIds(List<Long> orderIds) {
        UnifiedOrderExample unifiedOrderExample = new UnifiedOrderExample();
        unifiedOrderExample.createCriteria().andIdIn(orderIds);
        unifiedOrderMapper.deleteByExample(unifiedOrderExample);
    }
    /****************************************** 工具方法 orderSns 推导   end ******************************************/

    /****************************************** 工具方法 accountingUnifiedCustomerOrderIds 推导 start ******************************************/

    // TODO 好像现在没用到

    /****************************************** 工具方法 accountingUnifiedCustomerOrderIds 推导   end ******************************************/

}
