<?php
/**
 * 商品管理模块
 * Created by PhpStorm.
 * User: wxj
 * Date: 2019/10/30
 * Time: 14:02
 */

namespace JinDouYun\Model\Goods;

use Exception;


use JinDouYun\Cache\PageCache;
use JinDouYun\Controller\GoodsManage\GoodsBasic;
use JinDouYun\Dao\Stock\DInventoryWarehouse;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\StatusCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Factory;

use JinDouYun\Cache\PriceCache;
use JinDouYun\Cache\ActivityLimitCache;
use JinDouYun\Cache\SpecCache;
use JinDouYun\Cache\GoodsBasicRelevant;

use JinDouYun\Controller\Common\Logger;


use JinDouYun\Model\Commission\MCommissionSetting;
use JinDouYun\Model\Merchant\MMerchant;
use JinDouYun\Model\Purchase\MPurchase;
use JinDouYun\Model\Purchase\MSupplier;
use JinDouYun\Model\System\MDeliverySetting;
use JinDouYun\Model\GoodsManage\MSku;
use JinDouYun\Model\GoodsManage\MGoodsBasic;
use JinDouYun\Model\GoodsManage\MGoodsBrand;
use JinDouYun\Model\GoodsCategory\MGoodsCategory;
use JinDouYun\Model\Shop\MShop;
use JinDouYun\Model\Stock\MInventory;
use JinDouYun\Model\Price\MPrice;
use JinDouYun\Model\Price\MPriceAdjustment;
use JinDouYun\Model\MBaseModel;
use JinDouYun\Model\Cart\MCart;
use JinDouYun\Model\Customer\MCustomer;
use JinDouYun\Model\Market\MActivity;
use JinDouYun\Model\Customer\MCustomerVisitsLog;
use JinDouYun\Model\Goods\MGoodsSupport;
use JinDouYun\Model\Price\MCustomerTypePriceAdjustment;

use JinDouYun\Dao\Enterprise\DEnterprise;
use JinDouYun\Dao\GoodsManage\DSku;
use JinDouYun\Dao\Shop\DShop;
use JinDouYun\Dao\Goods\DGoods;
use JinDouYun\Dao\GoodsManage\DGoodsBasic;









use Util\Common\ChineseCharacter;


class MGoods extends MBaseModel
{

    /**
     * @var DGoods
     */
    private $objDGoods;

    /**
     * @var MGoodsBasic
     */
    private $objMGoodsBasic;

    /**
     * @var MGoodsCategory
     */
    private $objMGoodsCategory;

    /**
     * @var MGoodsBrand
     */
    private $objMGoodsBrand;

    /**
     * @var MShop
     */
    private $objMShop;

    /**
     * @var MInventory
     */
    private $objMInventory;

    /**
     * @var MPrice
     */
    private $objMPrice;

    /**
     * @var MPriceAdjustment
     */
    private $objMPriceAdjustment;

    /**
     * @var MGoodsCollect
     */
    private $objMGoodsCollect;

    /**
     * @var MCustomer
     */
    private $objMCustomer;

    /**
     * 客户ID
     * @var integer
     */
    private $useCustomerId = null;

    /**
     * 客户类型
     * @var integer
     */
    private $customerType = null;

    /**
     * @var int
     */
    private $cutTable = 1;//商品按照企业id分表

    /**
     * @var int
     */
    private $enterpriseId;

    /**
     * true=>app false=>manage
     * @var bool
     */
    public $isFront;//是否是前台调用此Model

    /**
     * @var
     */
    private $userCenterId;

    /**
     * @var null
     */
    private $selectUserCenterId = null;//选择的用户id

    /**
     * @var ActivityLimitCache
     */
    private $objActivityLimitCache;

    /**
     * @var SpecCache
     */
    private $objSpecCache;

    /**
     * @var MActivity
     */
    private $objMActivity;

    /**
     * 公共数据
     * @var array
     */
    private $commonMapping = [];

    /**
     * @var MSku
     */
    private $objMSku;

    /**
     * @var array
     */
    private $allMappingSpec = [];

    /**
     * @var DGoodsBasic
     */
    private $objDGoodsBasic;

    /**
     * @var MCommissionSetting
     */
    private $objMCommissionSetting;

    /**
     * @var DSku
     */
    private $objDSku;

    /**
     * @var DShop
     */
    private $objDShop;


    /**
     * MGoods constructor.
     * @param $enterpriseId
     * @param bool $isFront
     * @param $userCenterId
     * @throws Exception
     */
    public function __construct($enterpriseId, $isFront = false, $userCenterId)
    {
        $this->userCenterId = $userCenterId;
        $this->enterpriseId = $enterpriseId;
        $this->isFront = $isFront;
        parent::__construct($enterpriseId, $userCenterId);

        $this->objMGoodsBasic       = new MGoodsBasic($userCenterId, $enterpriseId);
        $this->objMGoodsBrand       = new MGoodsBrand($userCenterId, $enterpriseId);
        $this->objMGoodsCategory    = new MGoodsCategory($userCenterId, $enterpriseId);
        $this->objMShop             = new MShop($enterpriseId, $userCenterId);
        $this->objMPrice            = new MPrice($this->userCenterId, $enterpriseId);
        $this->objMPriceAdjustment  = new MPriceAdjustment($userCenterId, $enterpriseId);
        $this->objMGoodsCollect     = new MGoodsCollect($enterpriseId, $userCenterId);
        $this->objMCustomer         = new MCustomer($this->enterpriseId, $this->userCenterId);
        $this->objActivityLimitCache = new ActivityLimitCache($this->enterpriseId);
        $this->objMActivity         = new MActivity($this->userCenterId, $this->enterpriseId);
        $this->objMSku              = new MSku($this->userCenterId, $this->enterpriseId);
        $this->objSpecCache         = new SpecCache($this->enterpriseId);
        $this->objMInventory        = new MInventory($this->enterpriseId,$this->userCenterId);
        $this->objMCommissionSetting = new MCommissionSetting($this->enterpriseId,$this->userCenterId);

        $this->objDSku              = new DSku();
        $this->objDShop             = new DShop();
        $this->objDGoodsBasic       = new DGoodsBasic();
        $this->objDGoods            = new DGoods('default');

        $tableName = $this->objDGoods->getTableName('qianniao_goods_', $this->enterpriseId, $this->cutTable);
        $this->objDGoods->setTable($tableName);
        $this->objDGoods->setSearchIndex('goods_search')->setType('goods');
        $this->objDShop->setTable('qianniao_shop_1');
        $this->objDSku->setTable('qianniao_sku_'.$this->enterpriseId);

        if ($this->isFront && $this->userCenterId) {
            self::__initCustomer($this->userCenterId, $this->enterpriseId);
        }
    }

    /**
     * @param $userCenterId
     * @param $enterpriseId
     * @throws Exception
     */
    public function __initCustomer($userCenterId, $enterpriseId)
    {
        $objMCustomer = new MCustomer($enterpriseId, $userCenterId);
        $dbResult = $objMCustomer->getCustomerInfoByUserCenterId($userCenterId);
        if (!$dbResult->isSuccess()) {
            return ResultWrapper::fail($dbResult->getData(), $dbResult->getErrorCode());
        }
        $customer = $dbResult->getData();
        $this->customerType = isset($customer['type']) ? $customer['type'] : 0;
        $this->useCustomerId = $customer['id'];
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/8/25
     * Time: 4:24 下午
     * @param array $rows
     * @param $v
     * @param $item
     * @param int $index
     */
    private function buildExportFinalData(&$rows, $v, $item, int $index)
    {
        $rows['id'] = '';
        $rows['goodsCode'] = '';
        $rows['goodsName'] = '';
        $rows['categoryName'] = '';
        $rows['brandName'] = '';
        $rows['expireTime'] = '';
        $rows['inventoryTotalNum'] = '';
        $rows['salesTotalNum'] = '';
        $rows['enableStatusMsg'] = '';
        $rows['shopName'] = '';
        $rows['tag'] = '';
        $rows['describe'] = '';
        $rows['storageCode'] = '';
        $rows['createTime'] = '';
        if ($index == 0){
            $rows['id'] = $v['id'];
            $rows['goodsCode'] = $v['goodsCode'];
            $rows['goodsName'] = $v['goodsName'];
            $rows['categoryName'] = $v['categoryName'];
            $rows['brandName'] = empty($v['brandName']) ? $v['brandName'] : '无';
            $rows['expireTime'] = $v['expireTime'];
            $rows['inventoryTotalNum'] = !empty($v['inventoryNum']) ?$v['inventoryNum']:0;
            $rows['salesTotalNum'] = $v['salesTotalNum'];
            $rows['enableStatusMsg'] = $v['enableStatusMsg'];
            $rows['shopName'] = $v['shopName'];
            $rows['tag'] = empty($v['tag']) ? $v['tag'] : '无';
            $rows['describe'] = $v['describe'];;
            $rows['storageCode'] = empty($v['storage']) ? $v['storage'] : '无';
            $rows['createTime'] = $v['createTime'];
        }
        $rows['unitName'] = $item['unitName'];
        $rows['specGroup'] = $item['specGroup'];
        $rows['marketPrice'] = $item['marketPrice'];
        $rows['salePrice'] = $item['salePrice'];
        $rows['ladderPriceMsg'] = $item['ladderPriceMsg'];
        $rows['barCode'] = $item['barCode'];
        $rows['skuMsg'] = $item['skuMsg'];
        $rows['conversion'] = $item['conversion'];
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/8/25
     * Time: 4:17 下午
     * @param array $result
     *
     */
    private function exportCsv( $result)
    {
//        //导出到本地
        header("Content-type:application/vnd.ms-excel");
        header("Content-Disposition:filename=GoodsBasicCsv.csv");
        header('Cache-Control: max-age=0');
        $fp = fopen('php://output', 'a');
        $head = ['ID', '商品编码', '商品名称', '商品分类', '商品品牌', '保质期', '总库存','总销量','当前状态', '所属店铺', '关键词','商品卖点', '货架编码','发布日期',
            '计量单位', '规格', '市场价格(元)','销售价格(元)' , '阶梯价格', '商品条码' , '主单位(主/辅)', '主辅换算比率',];//定义标题
        foreach ($head as $i => $v) {
            $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8');     //将中文标题转换编码，否则乱码
        }
        fputcsv($fp, $head);
        $limit = 10000;
        $num = 0;//计数器
        $rows = [];
        foreach ($result as $v) {
            $num++;
            if($num == $limit){
                ob_flush();         //释放内存
                flush();
            }
            foreach ($v['specMultiple'] as $index => $item){
                self::buildExportFinalData($rows,$v,$item,$index);
                foreach ($rows as $kk => $vv) {
                    $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
                }
                fputcsv($fp, $rs);
                $rows = [];
            }
        }
        exit;
    }
    
    /**
     * 商品列表
     * @param array $result
     */
    private function exportGoodsList($result)
    {
       
        //导出到本地
        header("Content-type:application/vnd.ms-excel");
        header("Content-Disposition:filename=商品列表.csv");
        header('Cache-Control: max-age=0');
        $fp = fopen('php://output', 'a');
        $head = ['ID', '商品编码', '商品名称', '商品分类', '商品品牌', '总库存','总销量','当前状态', '所属店铺', '关键词', '发布日期',
            '计量单位', '规格' , '商品条码'];//定义标题
        foreach ($head as $i => $v) {
            $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8');     //将中文标题转换编码，否则乱码
        }

        fputcsv($fp, $head);
    
        $limit = 10000;
        $num = 0;                                         //计数器
        foreach ($result as $v) {                           //循环数据
            $num++;
            if ($num == $limit) {
                ob_flush();         //释放内存
                flush();
            }
            $rows['id']   = isset($v['id']) ? $v['id'] : ''; //ID
            $rows['code'] = isset($v['code']) ? $v['code'] : ''; //商品编码
            $rows['title'] = isset($v['title']) ? $v['title'] : ''; //商品名称
            $rows['categoryName'] = isset($v['categoryName']) ? $v['categoryName'] : '无'; //商品分类
            $rows['brandName']    = isset($v['brandName']) ? $v['brandName'] : '无'; //商品品牌
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //保质期
            $rows['inventorTotal'] = isset($v['inventorTotal']) ? $v['inventorTotal'] : 0; //总库存
            $rows['realSalesNum'] = isset($v['realSalesNum']) ? $v['realSalesNum'] : 0; //总销量
            $rows['enableStatus'] = isset($v['enableStatus']) && $v['enableStatus']== 5 ? '上架' : '下架'; //当前状态
            $rows['shopName']     = isset($v['shopName']) ? $v['shopName'] : ''; //所属店铺
            $rows['tag']          = empty($v['tag']) ? $v['tag'] : '无';; //关键词
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //商品卖点
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //货架编码
            $rows['createTime']    = date("Y-m-d H:i:s",$v['createTime']) ; //发布日期
            $rows['unitNameMaster'] = isset($v['unitNameMaster']) ? $v['unitNameMaster'] : ''; //计量单位
            $rows['specGroup']   = empty($v['specGroup']) ? '无' : self::createSpecName(json_decode($v['specGroup'],true));; //规格
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //市场价格(元)
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //销售价格(元)
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //阶梯价格
            $rows['barCode'] = isset($v['barCode']) ? $v['barCode'] : '无'; //商品条码
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //主单位(主/辅)
//            $rows['materielName'] = isset($v['materielName']) ? $v['materielName'] : ''; //主辅换算比率
            
            foreach ($rows as $kk => $vv) {
                $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8');  //转译编码
            }
            fputcsv($fp, $rs);
        
            $rows = [];
        }
    }
    /**
     * 兼容原来的数据
     * 将sku转化为spec格式
     * @param $data
     * @return mixed
     */
    public function formatSkuTransSpecMapping($data)
    {
        if (empty($data)) {
            return $data;
        }
        foreach ($data as &$details) {
            if (!isset($details['specType'])) {
                $details['specType'] = StatusCode::$specType['single'];//之前es中没有
            }
            if ($details['specType'] == StatusCode::$specType['multiple']) {
                continue;
            }
            $skuData = $details['skuData'];
            if (empty($skuData)) {
                continue;
            }

            $params = [];
            $specMultiple = [];
            foreach ($skuData as $row) {
                $params[] = [
                    'name'        => $row['unitName'],
                    'specValueId' => $this->objSpecCache->getIdBySpecName($row['unitName']),
                ];
                //规格明细
                $specMultiple[] = [
                    'id'         => $row['skuId'],//skuid
                    'isMaster'   => $row['isMaster'],
                    'conversion' => $row['conversion'],
                    'specGroup'  => [
                        [
                            'specId'          => $this->objSpecCache->getIdBySpecName('计量单位'),
                            'specIdName'      => '计量单位',
                            'specValueId'     => $this->objSpecCache->getIdBySpecName($row['unitName']),
                            'specValueIdName' => $row['unitName'],
                        ]
                    ],
                    'specImage'  => $details['images'],
                ];
            }

            //规格组
            $specGroup = [
                [
                    'groupSpec' => [
                        'name'   => '计量单位',
                        'specId' => $this->objSpecCache->getIdBySpecName('计量单位'),
                    ],
                    'params'    => $params
                ]
            ];

            $details['specGroup'] = $specGroup;
            $details['specMultiple'] = $specMultiple;
        }
        return $data;
    }

    /**
     * Doc: (des="商品数据es写入")
     * User: XMing
     * Date: 2020/7/20
     * Time: 9:59 上午
     * @param int $goodsId
     * @return bool
     */
    public function updateEsData_1(int $goodsId)
    {
        $fields = 'g.*,
                   s.warehouseId,
                   b.title,b.categoryId,b.categoryPath,b.brandId,b.images,b.describe,b.tag,b.expireTime,b.noSalesShop,b.description';
        $sql = 'select '.$fields.' from qianniao_goods_'.$this->enterpriseId.' as g 
                left join qianniao_goods_basic_'.$this->enterpriseId.' as b 
                on b.id = g.basicGoodsId 
                left join qianniao_shop_1 as s 
                on g.shopId = s.id 
                where g.id = '.$goodsId;
        $goods = $this->objDGoods->query($sql);
        if ($goods === false){
            return false;
        }

        $goods = isset($goods[0]) ? $goods[0] : [];
        if (empty($goods)){
            return false;
        }

        isset($goods['images']) && is_string($goods['images']) && $goods['images'] = json_decode($goods['images'],true);
        isset($goods['salesNum']) && is_string($goods['salesNum']) && $goods['salesNum'] = json_decode($goods['salesNum'],true);
        $goods['code'] = createCode(StatusCode::$code['goodsBasic']['prefix'], $goods['basicGoodsId'], StatusCode::$code['goodsBasic']['length']);//当前状态
        $_id = self::createEsDocumentId($goodsId);
        $result = $this->objDGoods->addUpSearchIndexDocument($goods,$_id);
        if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
            return true;
        }
        return false;
    }


    /**
     * todo(这个方法需要更新掉)
     * @param $goodsId
     * @throws Exception
     */
    public function updateEsData($goodsId)
    {
        //每次查询一遍，避免商品在数据库存在，在ES中不存在的情况
        $goods = $this->objDGoods->get_by('id', $goodsId);
        if ($goods !== false) {
            //查出商铺对应的仓库id
            $shop = $this->objMShop->getShopName([$goods['shopId']]);
            $shop = !empty($shop) ? array_shift($shop) : [];
            $goods['warehouseId'] = isset($shop['warehouseId']) ? $shop['warehouseId'] : 0;
            $goods['enterpriseId'] = $this->enterpriseId;
            //$goods['specification'] = json_decode($goods['specification'], true);
            $goods['salesNum'] = empty($goods['salesNum']) ? $goods['salesNum'] : json_decode($goods['salesNum'], true);

            $_id = self::createEsDocumentId($goodsId);
            $result = $this->objDGoods->addUpSearchIndexDocument($goods, $_id);

            if (isset($result['_shards']) && isset($result['_shards']['successful']) && $result['_shards']['successful'] == 1) {
                //echo "es操作成功";die;
            } else {
                file_put_contents('/www/wwwroot/logs/api.junhailan.com/elasticsearch.log', date('Y-m-d H:i:s') . '操作商品es错误，错误原因' . var_export($result, true) . PHP_EOL, FILE_APPEND);

            }
        }
    }

    /**
     * Doc: (des="生成文档id")
     * User: XMing
     * Date: 2020/7/20
     * Time: 10:49 上午
     * @param $goodsId
     * @return string
     */
    private function createEsDocumentId($goodsId)
    {
        return 'EnterpriseId_' . $this->enterpriseId . '_GoodsId_' . $goodsId;
    }

    /**
     * 添加商品
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function addGoods($params)
    {
       
        $existResult = $this->existGoodsInShop($params['shopId'], $params['basicGoodsId']);

        if ($existResult->isSuccess() == false) {
            return ResultWrapper::fail($existResult->getData(), $existResult->getErrorCode());
        }

        $basic = $this->objMGoodsBasic->getBasicById($params['basicGoodsId']);

        if (empty($basic)){
            return ResultWrapper::fail('未获取到物料信息',ErrorCode::$paramError);
        }
        $params['merchantId'] = $basic['merchantId'];
        $params['supplierId'] = getArrayItem($basic,'supplierId',0);
        $priceData = $params['priceData'];
        unset($params['priceData']);

        $priceAdjustmentData['createUserName'] = $params['createUserName'];
        unset($params['createUserName']);
        $priceAdjustmentData['shopName'] = $params['shopName'];
        unset($params['shopName']);
        $priceAdjustmentData['goodsName'] = $params['goodsName'];

        unset($params['goodsName']);
        $commissionResult = $this->objMCommissionSetting->getSetting('goods');
        if (!$commissionResult->isSuccess()){
            return ResultWrapper::fail($commissionResult->getData(),$commissionResult->getErrorCode());
        }

        $params['isJoinCommission'] = !empty($commissionResult->getData()) ? $commissionResult->getData() : StatusCode::$delete;
        $this->objDGoods->beginTransaction();

        $params['staffId'] = $this->userCenterId;
        $goodsId = $this->objDGoods->insert($params);
        if ($goodsId === false) {
            $this->objDGoods->rollBack();
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        //self::updateEsData($goodsId);

        if (empty($priceData)) {
            $this->objDGoods->commit();
            return ResultWrapper::success($goodsId);
        }

        // 同步生成商品价格调价单
        $priceAdjustmentData = self::savePriceData($goodsId, $params, $priceData, $priceAdjustmentData, 'add');
        $effectiveParams = [
            'createTime'        => time(),
            'effectiveUserName' => $priceAdjustmentData['createUserName'],
            'effectiveUserId'   => $this->userCenterId,
        ];

        $result = $this->objMPriceAdjustment->addAndEffective([$priceAdjustmentData], $effectiveParams);
        if (!$result->isSuccess()) {
            $this->objDGoods->rollBack();
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        $this->objDGoods->commit();
        // 每发布一件商品需要清除一下小程序商品首页的缓存;
        $objPageCache = new PageCache();
        $objPageCache->delPage();
        return ResultWrapper::success($goodsId);
    }

    public function existGoodsInShop($shopId, $basicGoodsId)
    {
        $where = [
            'shopId'       => $shopId,
            'basicGoodsId' => $basicGoodsId,
            'deleteStatus' => StatusCode::$standard
        ];
        $result = $this->objDGoods->select($where);
        if ($result === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }

        if (!empty($result)) {
            return ResultWrapper::fail('商铺下已存在相同商品', ErrorCode::$dberror);
        }
        return ResultWrapper::success('未添加此商品');
    }

    /**
     * 生效商品价格
     */
    public function savePriceData($goodsId, $params, $priceData, $priceAdjustmentData, $action)
    {
        $priceAdjustmentCommonData = [
            'createUserId'      => $this->userCenterId,
            'goodsId'           => $goodsId,
            'saleType'          => 1,
            'salePriceType'     => 1,
            'salePriceAreaType' => 1,
            'shopId'            => $params['shopId'],
            'createTime'        => time(),
            'updatetime'        => time(),
        ];



        foreach ($priceData as $key => $value) {
            $savePriceData = [
                'salePrice'     => isset($value['salePrice']) ? floatval($value['salePrice']) : 0,
                'memberPrice'     => isset($value['memberPrice']) ? floatval($value['memberPrice']) : 0,
                'marketPrice'   => isset($value['marketPrice']) ? $value['marketPrice'] : 0,
                'ladderPrice'   => $value['ladderPrice'],
                'unitName'      => isset($value['unitName']) ? $value['unitName'] : '',
                'unitId'        => isset($value['unitId']) ? $value['unitId'] : 0,
                'enabledLadder' => $value['enabledLadder'],
                'setNum'        => isset($value['setNum']) ? $value['setNum'] : 0,//起订数量
                'isSale'        => getArrayItem($value, 'isSale', StatusCode::$standard),
                'minUnitPriceConvert' => getArrayItem($value, 'minUnitPriceConvert', 0),
            ];

            $priceAdjustmentData['salePrice'][$value['id']] = $savePriceData;
        }


        $priceAdjustmentData['salePrice'] = json_encode($priceAdjustmentData['salePrice']);

        $priceAdjustmentData = array_merge($priceAdjustmentData, $priceAdjustmentCommonData);

        return $priceAdjustmentData;
    }

    /**
     * 编辑商品
     * @param $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function editGoods($params)
    {
        if (empty($params['id'])) {
            return ResultWrapper::fail('没有指定要修改的商品id', ErrorCode::$paramError);
        }

        $updateGoodsId = $params['id'];
        unset($params['id']);

        $priceData = $params['priceData'];
        unset($params['priceData']);
        $priceAdjustmentData['createUserName'] = $params['createUserName'];
        unset($params['createUserName']);
        $priceAdjustmentData['shopName'] = $params['shopName'];
        unset($params['shopName']);
        $priceAdjustmentData['goodsName'] = $params['goodsName'];
        unset($params['goodsName']);


        $beginTransactionStatus = $this->objDGoods->beginTransaction();

        $dbResult = $this->objDGoods->update($params, $updateGoodsId);
        if ($dbResult === false) {
            $this->objDGoods->rollBack();
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }

//        self::updateEsData($updateGoodsId);

        if (empty($priceData)) {
            return ResultWrapper::success($updateGoodsId);
        }

        // 同步生成商品价格调价单
        $priceAdjustmentData = self::savePriceData($updateGoodsId, $params, $priceData, $priceAdjustmentData, 'edit');

        $effectiveParams = [
            'createTime'        => time(),
            'effectiveUserName' => $priceAdjustmentData['createUserName'],
            'effectiveUserId'   => $this->userCenterId,
        ];

        $result = $this->objMPriceAdjustment->addAndEffective([$priceAdjustmentData], $effectiveParams);
        if (!$result->isSuccess()) {
            $this->objDGoods->rollBack();
            return ResultWrapper::fail($result->getData(), $result->getErrorCode());
        }

        if($beginTransactionStatus){
            $this->objDGoods->commit();
        }

        return ResultWrapper::success($dbResult);
    }

    /**
     * 修改商品的销量
     * @param $goodsId
     * @param $skuId
     * @param $num 下单 加销量传正数，退货减销量传负数
     * @return bool
     */
    public function updateSalesNum($goodsId, $skuId, $num)
    {
        $goodsInfo = $this->objDGoods->get($goodsId);
        $salesNumInfo = empty($goodsInfo['salesNum']) ? [] : json_decode($goodsInfo['salesNum'], true);
        $exist = false;
        $realSalesNum = $goodsInfo['realSalesNum'];

        foreach ($salesNumInfo as &$salesNum) {
            if (isset($salesNum['skuId']) && $salesNum['skuId'] == $skuId) {
                $salesNum['salesNum'] = $salesNum['salesNum'] + $num;
                $exist = true;
            }
        }

//        if(!empty($salesNumInfo)){
//            $skuIds = array_column($salesNumInfo,'skuId');
//            var_dump(array_search($skuId, $skuIds));
//            var_dump($skuIds);
//            var_dump($skuId);
//            if(array_search($skuId, $skuIds) === false){
//                var_dump(111);
//                array_push($salesNumInfo, ['skuId' => $skuId, 'salesNum' => $num]);
//            }
//        }

        if (!$exist) {
            array_push($salesNumInfo, ['skuId' => $skuId, 'salesNum' => $num]);
        }

        //循环销量数据,更新真实销量
        $objDSku = new DSku();
        $objDSku->setTable('qianniao_sku_'.$this->enterpriseId);
        //查询sku表
        $skuResult = $objDSku->get(['id'=>$skuId]);
        if ($skuResult === false) {
            return false;
        }
        if(empty($skuResult)){
            return false;
        }
        if($skuResult['isMaster'] == StatusCode::$standard){//主单位直接累加
            $realSalesNum = $realSalesNum + $num;
        }
        if($skuResult['isMaster'] == StatusCode::$delete){ //副单位换算
            $realSalesNum = $realSalesNum + bcmul($num,$skuResult['conversion']);
        }

        $result = $this->objDGoods->update(['salesNum' => json_encode($salesNumInfo),'realSalesNum'=>$realSalesNum], $goodsId);
        if ($result) {
            //更新ES
            //$_id = self::createEsDocumentId($goodsId);
            //$this->objDGoods->esupdateTypeFieldVaule(['salesNum' => $salesNumInfo], $_id);
            return true;
        }
        return false;
    }

    /**
     * Doc: (des="审核商品")
     * User: XMing
     * Date: 2020/12/7
     * Time: 11:32 上午
     * @param int $id
     * @return ResultWrapper
     */
    public function audit(int $id): ResultWrapper
    {
        $dbResult = $this->objDGoods->update(['auditStatus' => StatusCode::$auditStatus['auditPass'] ,'updateTime' => time()], $id);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        /*
        //更新ES
        $_id = self::createEsDocumentId($id);
        $this->objDGoods->esupdateTypeFieldVaule(['auditStatus' => StatusCode::$auditStatus['auditPass'],'updateTime' => time()], $_id); */
        return ResultWrapper::success(true);
    }

    /**
     * 删除商品 只支持单个
     * @param $delGoodsIds
     * @return ResultWrapper
     * @throws Exception
     */
    public function delGoods($delGoodsIds)
    {
        if (empty($delGoodsIds)) {
            return ResultWrapper::fail('参数错误', ErrorCode::$paramError);
        }

        $this->objDGoods->beginTransaction();

        $dbResult = $this->objDGoods->update(['deleteStatus' => StatusCode::$delete], $delGoodsIds);
        if ($dbResult === false) {
            $this->objDGoods->rollBack();
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        } else {
            $result = self::delGoodsBasic($delGoodsIds);
            if (!$result->isSuccess()){
                $this->objDGoods->rollBack();
                return ResultWrapper::fail($result->getData(),$result->getErrorCode());
            }
            $this->objDGoods->commit();
            /*
            //在ES删除
            $_id = self::createEsDocumentId($delGoodsIds);
            $this->objDGoods->esdeleteTypeDocument($_id); */
            return ResultWrapper::success($dbResult);
        }

    }

    /**
     * 单店铺删除基础商品资料
     * @param int $id
     * @return ResultWrapper
     * @throws Exception
     */
    public function delGoodsBasic(int $id)
    {
        $objDEnterprise = new DEnterprise();
        $objDEnterprise->setTable('qianniao_enterprise_1');
        $field = $objDEnterprise->get_field('scope',['id'=>$this->enterpriseId]);
        if ($field === false){
            Logger::logs(E_USER_ERROR,'查询错误',__CLASS__,__LINE__,$objDEnterprise->error());
            return ResultWrapper::fail($objDEnterprise->error(),ErrorCode::$dberror);
        }

        if ($field == StatusCode::$standard){
            return ResultWrapper::success($id);
        }

        $basicGoodsId = $this->objDGoods->get_field('basicGoodsId',['id'=>$id]);
        if ($field === false){
            Logger::logs(E_USER_ERROR,'查询错误',__CLASS__,__LINE__,$this->objDGoods->error());
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $result = $this->objMGoodsBasic->delGoodsBasic($basicGoodsId);
        if (!$result->isSuccess()){
            return ResultWrapper::fail($result->getData(),$result->getErrorCode());
        }
        return ResultWrapper::success('操作成功');
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/24
     * Time: 2:56 下午
     * @param $selectParams
     * @return ResultWrapper
     * @throws Exception
     */
    private function getCustomerIdAndCustomerTypeByUserCenterId($selectParams): ResultWrapper
    {
        $customer = [];
        if (isset($selectParams['userCenterId']) && !empty($selectParams['userCenterId'])){
            $objMCustomer = new MCustomer($this->enterpriseId,$this->userCenterId);
            $customerResult = $objMCustomer->getCustomerDataByUserCenterIdAndEnterpriseId($selectParams['userCenterId']);
            if (!$customerResult->isSuccess()){
                return ResultWrapper::fail($customerResult->getData(),$customerResult->getErrorCode());
            }
            $customer = $customerResult->getData();
            $this->useCustomerId = getArrayItem($customer,'id',0);
            $this->customerType = getArrayItem($customer,'type',0);
        }
        return ResultWrapper::success($customer);
    }

    /**
     * 获取指定商品信息
     * @param $goodsId
     * @param int $userCenterId
     * @return ResultWrapper
     * @throws Exception
     */
    public function getGoodsInfo($goodsId,$userCenterId = null)
    {
        // 获取商品表数据
        $dbResult = $this->objDGoods->get_by('id', $goodsId);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        if( empty($dbResult) ){
            return ResultWrapper::fail('查询的商品数据为空', ErrorCode::$contentNotExists);
        }

        // 处理客户列表数据
        $formatGoodsResult = self::formatManageGoodsLists([$dbResult]);
        if (!$formatGoodsResult->isSuccess()){
            return ResultWrapper::fail($formatGoodsResult->getData(),$formatGoodsResult->getErrorCode());
        }
        $formatGoods = $formatGoodsResult->getData();
        $goodsData = array_shift($formatGoods);

        // 处理商品详情数据
        $formatDetailsResult = self::formatDetails($goodsData);
        if (!$formatDetailsResult->isSuccess()){
            return ResultWrapper::fail($formatDetailsResult->getData(),$formatDetailsResult->getErrorCode());
        }
        $goodsDetails = $formatDetailsResult->getData();

        // 格式化经营屏蔽数据
        $customerNotResult = self::formatNotCustomer($goodsDetails);
        if (!$customerNotResult->isSuccess()){
            return ResultWrapper::fail($customerNotResult->getData(),$customerNotResult->getErrorCode());
        }
        $dbResult = $customerNotResult->getData();

        return ResultWrapper::success($dbResult);
    }

    /**
     * Doc: (des="获取所有商品数据")
     * User: XMing
     * Date: 2020/11/30
     * Time: 10:29 上午
     * @param array $selectParams 查询条件
     * @param string $fields 查询字段
     * @param string $order 排序方式
     * @param bool $export 是否为导出 true=>导出
     * @return ResultWrapper
     * @throws Exception
     */
    public function getAllGoods(array $selectParams,string $fields = '*',string $order = 'topTime DESC, sort desc, createTime desc',bool $export = false): ResultWrapper
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);


        $returnData = [
            'data'   => [],
            'total'  => 0,
        ];

        $where = "deleteStatus =" . StatusCode::$standard;
        if (isset($selectParams['enableStatus'])) {
            $where .= " AND enableStatus = " . $selectParams['enableStatus'];
        }

        if (isset($selectParams['shopId'])) {
            if (is_array($selectParams['shopId'])) {
                $where .= " AND shopId in (" . implode(',', $selectParams['shopId']) . ')';
            } else {
                $where .= " AND shopId = " . $selectParams['shopId'];
            }
        }

        if (isset($selectParams['isOption']) && !empty($selectParams['isOption'])){
            $where .= " AND isOption = " . $selectParams['isOption'];
        }

        if (isset($selectParams['supplierId']) && !empty($selectParams['supplierId'])){
            $where .= ' AND supplierId = '.$selectParams['supplierId'];
        }

        if (isset($selectParams['auditStatus']) && !empty($selectParams['auditStatus'])){
            $where .= " AND auditStatus = " . $selectParams['auditStatus'];
        }
        
        if (isset($selectParams['inStock'])) {
            // 获取有无库存的基本资料id
            $goodsBasicIdResult = self::getInOrOutOfStockGoodsBasicId($selectParams['inStock']);
            if (!$goodsBasicIdResult->isSuccess()) {
                return ResultWrapper::fail($goodsBasicIdResult->getData(), $goodsBasicIdResult->getErrorCode());
            }
            $goodsBasicIds = $goodsBasicIdResult->getData();
            if (!empty($goodsBasicIds)) {
                $where .= " AND (";
                foreach ($goodsBasicIds as $key => $goodsBasicId) {
                    $condition = $key ? " OR " : "";
                    $where .= $condition . '(basicGoodsId = ' . $goodsBasicId['basicGoodsId'] . ' and shopId=' . $goodsBasicId['shopId'] . ')';
                }
                $where .= ")";
            }
        }
        
        if( isset($selectParams['merchantId']) ){
            $where .= ' AND merchantId = '.$selectParams['merchantId'];
        } else {
            if (isset($selectParams['ifMerchant']) ){
                if($selectParams['ifMerchant'] == StatusCode::$delete){
                    $where .= ' AND merchantId = 0';
                } else {
                    $where .= ' AND merchantId <> 0';
                }
            }
        }

        // 查询总条数
        $total = $this->objDGoods->count($where);
        if ($total === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        if(empty($total)){
            return ResultWrapper::success($returnData);
        }
     
        //数据域
        //$selectParams = parent::getStaffQueryParams($where, 'staffId');//商品不应该有数据域
        //$selectParams = parent::getShopIdQueryParams($selectParams);//店铺数据域
        // 导出
        if ($export === true){
            self::exportGoods($where,'db');
            exit;
        }
        $dbResult = $this->objDGoods->select($where, $fields, $order, $limit, $offset);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        // 格式化商品数据
        $formatResult = self::formatManageGoodsLists($dbResult);
        if (!$formatResult->isSuccess()){
            return ResultWrapper::fail($formatResult->getData(),$formatResult->getErrorCode());
        }
        $return = [
            'data'  => $formatResult->getData(),
            'total' =>($total) ? intval($total) : 0,
        ];
        return ResultWrapper::success($return);
    }
    
    /**
     * 商品列表页
     */
    public function getAllGoodsList($selectParams,$export=0)
    {
        $goodsTab      = 'qianniao_goods_'.$this->enterpriseId;
        $goodsBasicTab = 'qianniao_goods_basic_'.$this->enterpriseId;
        $inventoryWarehouse = 'qianniao_inventory_warehouse_'.$this->enterpriseId;
        $shopTab       = 'qianniao_shop_1';
        // 初始化表
        $this->objDGoods->setTable($goodsTab);
        $objDGoodsBasic = new DGoodsBasic('default');
        $objDGoodsBasic->setTable($goodsBasicTab);
        $objDInventoryWarehouse = new DInventoryWarehouse('stock');
        $objDInventoryWarehouse->setTable($inventoryWarehouse);
        $stockDbName = Factory::config()->get('db.stock.dbname');
        
        // 组装检索sql
        $whereSql = '';
        if(isset($selectParams['keywordType']) && !empty($selectParams['keywordType'])){
            $whereSql .= self::assemblySql($selectParams['keywordType']);
        }
        // 商品关键字
    
        if (isset($selectParams['keyword']) && !empty($selectParams['keyword'])){
            $keywordId = 0;
            preg_match_all( '/\d+/' , $selectParams['keyword'] , $arr);
            if (isset($arr) && is_array($arr)){
                $arr = array_shift($arr);
                $keywordId = isset($arr[0]) ? (int)floatval($arr[0]) : 0;
            }
            $whereSql .= ' AND ( tmp.title like "%'.$selectParams['keyword'].'%" ';
            if (!empty($keywordId)){
                $whereSql .= ' OR tmp.basicId = '.$keywordId;
            }
            $whereSql .= ' ) ';
        }
        $where ='';
        if( isset($selectParams['merchantId']) && !empty($selectParams['merchantId']) ){
            $where .= ' AND g.merchantId = '.$selectParams['merchantId'];
        } else {
            if (isset($selectParams['ifMerchant'])  && !empty($selectParams['ifMerchant'])){
                if($selectParams['ifMerchant'] == StatusCode::$delete){
                    $where .= ' AND g.merchantId = 0  ';
                } else {
                    $where .= ' AND g.merchantId <> 0 ';
                }
            }
        }
    
        //分类路径
        if (isset($selectParams['categoryPath']) && !empty($selectParams['categoryPath'])){
            if (is_string($selectParams['categoryPath']) || is_int($selectParams['categoryPath'])){
                $selectParams['categoryPath'] = explode(',',$selectParams['categoryPath']);
            }
            $endPathId = array_pop($selectParams['categoryPath']);
            if (!empty($endPathId)){
                $whereSql .= ' and (find_in_set('.$endPathId.',tmp.categoryPath) or find_in_set('.$endPathId.',tmp.categoryId)) ';
            }
        }
        
        // 商品品牌
        if(isset($selectParams['brandId']) && !empty($selectParams['brandId'])){
            $whereSql .=' and tmp.brandId ='.$selectParams['brandId'];
        }
        // 销售店铺
        if(isset($selectParams['shopId']) && !empty($selectParams['shopId'])){
            $whereSql .=' and tmp.shopId ='.$selectParams['shopId'];
        }
        // 上下架
        if(isset($selectParams['enableStatus']) && !empty($selectParams['enableStatus'])){
            $whereSql .=' and tmp.enableStatus ='.$selectParams['enableStatus'];
        }
        
        if (isset($selectParams['limit']) && isset($selectParams['offset'])) {
            $limit = ' limit ' . $selectParams['offset'] . ',' . $selectParams['limit'];
        }else{
            $limit = '';
        }
        
      
        $order = '  GROUP BY tmp.id ORDER BY tmp.topTime DESC, tmp.sort desc, tmp.createTime desc';
        
        $fields = 'b.id as basicId, g.merchantId,g.staffId,g.images,g.serviceInfo,g.specification,g.content,g.isRecommend,
                   g.id,g.basicGoodsId,g.shopId,b.title,b.`code`,b.categoryPath,
                   b.categoryId,b.brandId,g.enableStatus,g.topTime,g.sort,g.createTime,
                   g.deleteStatus,g.updateTime,g.salesNum,g.specType,g.isJoinCommission,
                   g.isDefine,g.virtualSalesNum,g.deliverySupIds,g.expressType,g.ruleId,g.expressFee,g.showExpress,
                   g.auditStatus,g.isOption,g.supplierId,g.isShield,g.notArea,g.notCustomerType,g.notCustomer,g.isDistribution,
                   g.support,g.retType,g.goodsGroups,g.realSalesNum';
        // 导出
        if ($export){
           
            $sql = 'select tmp.*,s.warehouseId,sum(i.inventoryNum) inventoryNum,FIND_IN_SET(i.warehouseId,s.warehouseId)  from (
                  select  '.$fields.' from '.$goodsTab.' g left join '.$goodsBasicTab.' b on g.basicGoodsId = b.id
                where g.deleteStatus= '.StatusCode::$standard.'  and b.deleteStatus ='.StatusCode::$standard.$where.') tmp LEFT JOIN '.$shopTab.' s on s.id = tmp.shopId left join `'.$stockDbName.'`.'.$inventoryWarehouse.' i on i.materielId = tmp.basicGoodsId
                where tmp.deleteStatus='.StatusCode::$standard.$whereSql.$order;
            $dbResult = $this->objDGoods->exportQuery($sql);
            if ($dbResult === false) {
                return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
            }
            //格式化导出数据
            $formatListsResult = self::formatExportLists($dbResult);
            if (!$formatListsResult->isSuccess()){
                return ResultWrapper::fail($formatListsResult->getData(),$formatListsResult->getErrorCode());
            }
            $formatLists = $formatListsResult->getData();
            self::exportCsv($formatLists);
//            // 格式化商品数据
//            $formatResult = self::formatManageGoodsLists($dbResult);
//            if (!$formatResult->isSuccess()){
//                return ResultWrapper::fail($formatResult->getData(),$formatResult->getErrorCode());
//            }
//            self::exportGoodsList($formatResult->getData());
//            exit;
        }
        $sqlTotal = 'select count(*) as total from (
                  select  '.$fields.' from '.$goodsTab.' g left join '.$goodsBasicTab.' b on g.basicGoodsId = b.id
                where g.deleteStatus= '.StatusCode::$standard.'  and b.deleteStatus ='.StatusCode::$standard.$where.') tmp LEFT JOIN '.$shopTab.' s on s.id = tmp.shopId left join `'.$stockDbName.'`.'.$inventoryWarehouse.' i on i.materielId = tmp.basicGoodsId
                where tmp.deleteStatus='.StatusCode::$standard.$whereSql;
        
        $total = $this->objDGoods->query($sqlTotal);
        if ($total === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        if(empty($total[0]['total'])){
            $return = [
                'data'  => [],
                'total' => 0,
            ];
            return ResultWrapper::success($return);
        }
        $sql = 'select tmp.*,s.warehouseId,sum(i.inventoryNum) inventoryNum,FIND_IN_SET(i.warehouseId,s.warehouseId)  from (
                  select  '.$fields.' from '.$goodsTab.' g left join '.$goodsBasicTab.' b on g.basicGoodsId = b.id
                where g.deleteStatus= '.StatusCode::$standard.'  and b.deleteStatus ='.StatusCode::$standard.$where.') tmp LEFT JOIN '.$shopTab.' s on s.id = tmp.shopId left join `'.$stockDbName.'`.'.$inventoryWarehouse.' i on i.materielId = tmp.basicGoodsId
                where tmp.deleteStatus='.StatusCode::$standard.$whereSql.$order.$limit;

        $dbResult = $this->objDGoods->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        // 格式化商品数据
        $formatResult = self::formatManageGoodsLists($dbResult);
        if (!$formatResult->isSuccess()){
            return ResultWrapper::fail($formatResult->getData(),$formatResult->getErrorCode());
        }
       
    
        $return = [
            'data'  => $formatResult->getData(),
            'total' => isset($total[0]['total']) ? $total[0]['total'] : 0,
        ];
        
        return ResultWrapper::success($return);
    }
    
    /**
     * 根据商品列表 keywordType 拼装sql
     * @param $keywordType
     */
    public function  assemblySql($keywordType)
    {
        $whereSql = '';
        switch ($keywordType){
            case 1: // 全部商品 审核通过
                $whereSql .= '';
                break;
            case 2: //  销售中  上架且有库存  enableStatus 上下架（5上架 4下架）
                $whereSql .= ' and (FIND_IN_SET(i.warehouseId,s.warehouseId) OR tmp.isDistribution = '.StatusCode::$standard.') and tmp.enableStatus ='.StatusCode::$standard;
                break;
            case 3: // 已售罄  上架无库存
                $whereSql .= ' and ( FIND_IN_SET(i.warehouseId,s.warehouseId) =0 or FIND_IN_SET(i.warehouseId,s.warehouseId) is NUll  ) and tmp.enableStatus ='.StatusCode::$standard;
                break;
            case 4: // 仓库中  下架
                $whereSql .= ' and  FIND_IN_SET(i.warehouseId,s.warehouseId)  and tmp.enableStatus ='.StatusCode::$delete;
                break;
        }
        return $whereSql;
    }
    
    /**
     * Doc: (des="查询数据")
     * User: XMing
     * Date: 2020/8/25
     * Time: 11:00 上午
     * @param $data
     * @param string $source
     * @return ResultWrapper
     */
    private function getExportDataBySelectParams($data,string $source)
    {
        switch ($source){
            case 'db':
                $selectParams = $data;
                break;
            case 'es':
                $allIds = [];
                foreach ($data as $value){
                    $allIds[] = $value['id'];
                }
                if (empty($allIds)){
                    return ResultWrapper::fail('导出数据为空',ErrorCode::$paramError);
                }
                $selectParams['id'] = $allIds;
                break;
        }
        $goodsLists = $this->objDGoods->exportSelect($selectParams,'*','createTime DESC');
        if ($goodsLists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $list = self::getGeneratorData($goodsLists);
        return ResultWrapper::success($list);
    }

    /**
     * Doc: (des="获取export查询方法返回的数据集合")
     * User: XMing
     * Date: 2020/8/22
     * Time: 11:42 上午
     * @param $object
     * @return array
     */
    private static function getGeneratorData($object)
    {
        $arrayList = [];
        foreach ($object as $value){
            $arrayList[] = $value;
        }
        return $arrayList;
    }

    /**
     * Doc: (des="导出商品数据")
     * User: XMing
     * Date: 2020/8/25
     * Time: 10:57 上午
     * @param $data
     * @param string $source
     * @return ResultWrapper
     * @throws Exception
     */
    private function exportGoods($data,string $source)
    {
        $exportListsResult = self::getExportDataBySelectParams($data,$source);
        if (!$exportListsResult->isSuccess()){
            return ResultWrapper::fail($exportListsResult->getData(),$exportListsResult->getErrorCode());
        }
        $exportLists = $exportListsResult->getData();
        if (empty($exportLists)){
            return ResultWrapper::fail('导出数据为空',ErrorCode::$paramError);
        }
        //格式化导出数据
        $formatListsResult = self::formatExportLists($exportLists);
        if (!$formatListsResult->isSuccess()){
            return ResultWrapper::fail($formatListsResult->getData(),$formatListsResult->getErrorCode());
        }
        $formatLists = $formatListsResult->getData();
        self::exportCsv($formatLists);
    }

    /**git
     * Doc: (des="生成规格名字")
     * User: XMing
     * Date: 2020/8/22
     * Time: 2:47 下午
     * @param array $specGroup
     * @return string
     */
    private static function createSpecName(array $specGroup)
    {
        $str = '';
        foreach ($specGroup as $value){
            empty($str) && $str .= ' ';
            if (!empty($value['specName'])){
                $str .= $value['specName'].':';
            }
            if (!empty($value['specValueName'])){
                $str .= $value['specValueName'];
            }
        }
        return empty($str) ? '无' : $str;
    }

    /**
     * Doc: (des="格式化导出数据")
     * User: XMing
     * Date: 2020/8/25
     * Time: 11:26 上午
     * @param array $data
     * @return ResultWrapper
     * @throws Exception
     */
    private function formatExportLists(array $data)
    {
        if (empty($data)){
            return ResultWrapper::success([]);
        }
        $allGoodsBasicIds = [];
        $selectParam = [];
        $allShopIds = [];
        foreach ($data as $value){
            $allShopIds[] = $value['shopId'];
            $allGoodsBasicIds[] = $value['basicGoodsId'];
            $selectParam['material'][$value['shopId']][] = $value['id'];
        }
        $allShopIds = array_values(array_unique($allShopIds));
        $allGoodsBasicIds = array_values(array_unique($allGoodsBasicIds));
        if (empty($allGoodsBasicIds)){
            return ResultWrapper::fail('没有导出商品id',ErrorCode::$paramError);
        }
        $allGoodsBasicIdsStr = implode(',',$allGoodsBasicIds);
        $fields = ' b.*,c.title as categoryName,d.title as brandName ,b.expireTime';
        $sql = 'SELECT '.$fields.' FROM qianniao_goods_basic_'.$this->enterpriseId.' AS b 
                LEFT JOIN qianniao_goods_category_'.$this->enterpriseId.' as c 
                ON c.id = b.categoryId 
                LEFT JOIN qianniao_goods_brand_'.$this->enterpriseId.' as d 
                ON d.id = b.brandId 
                WHERE b.id in ('.$allGoodsBasicIdsStr.')';
        $queryLists = $this->objDGoods->exportQuery($sql);
        if ($queryLists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $queryLists = self::getGeneratorData($queryLists);
        if (empty($queryLists)){
            return ResultWrapper::fail('查询导出商品基础资料数据为空',ErrorCode::$paramError);
        }
        $goodsBasicMap = [];
        foreach ($queryLists as $list){
            $goodsBasicMap[$list['id']] = $list;
        }

        //获取sku数据
        $skuMap = [];
        if (!empty($allGoodsBasicIds)){
            $skuLists = $this->objDSku->exportSelect(['goodsId' => $allGoodsBasicIds,'deleteStatus' => StatusCode::$standard],'id,goodsId,conversion,unitName,isMaster,specData,barCode');
            if ($skuLists === false){
                return ResultWrapper::fail($this->objDSku->error(),ErrorCode::$dberror);
            }
            $skuLists = self::getGeneratorData($skuLists);
            foreach ($skuLists as &$value){
                $value['skuMsg'] = $value['isMaster'] == StatusCode::$standard ? '主' : '辅';
                $value['specGroup'] = empty($value['specData']) ? '无' : self::createSpecName(json_decode($value['specData'],true));
                $value['inventoryNum'] = 0;
                $value['salePrice'] = 0;
                $value['marketPrice'] = 0;
                $value['ladderPrice'] = '';
                $skuMap[$value['goodsId']][] = $value;
            }
            unset($skuLists);
            unset($value);
        }

        //获取商铺数据
        //查询店铺
        $shopMap = [];
        if (!empty($allShopIds)){
            $shopLists = $this->objDShop->exportSelect(['id'=>$allShopIds],'id,name,warehouseId');
            if ($shopLists === false){
                return ResultWrapper::fail($this->objDShop->error(),ErrorCode::$dberror);
            }
            $shopLists = self::getGeneratorData($shopLists);
            foreach ($shopLists as $value){
                $shopMap[$value['id']] = $value;
            }
            unset($value);
            unset($shopLists);
        }

        //获取商品的价格
        $priceResult = $this->objMPrice->getPrice($selectParam);
        if (!$priceResult->isSuccess()){
            return ResultWrapper::fail($priceResult->getData(),$priceResult->getErrorCode());
        }
        $priceMap  = $priceResult->getData();

        $inventorySelectParams = [];
        foreach ($data as &$datum){
            $datum['shopName'] = isset($shopMap[$datum['shopId']]) ? $shopMap[$datum['shopId']]['name'] : '无';
            $datum['warehouseId'] = isset($shopMap[$datum['shopId']]) ? $shopMap[$datum['shopId']]['warehouseId'] : '';
            $datum['specMultiple'] = isset($skuMap[$datum['basicGoodsId']]) ?  $skuMap[$datum['basicGoodsId']] : [];
            foreach ($datum['specMultiple'] as $item){
                $inventorySelectParams[$datum['shopId']][] = $item['id'];
            }
        }
        unset($datum);

        $inventoryMap = [];
        foreach ($inventorySelectParams as $shopId => $skuIds){
            $inventoryResult = $this->objMInventory->getInventoryByShopIdAndSkuIds($shopId,$skuIds);
            if (!$inventoryResult->isSuccess()){
                return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
            }
            $inventoryMap[$shopId] = $inventoryResult->getData();
        }

        foreach ($data as &$value){
            $value['inventoryTotalNum'] = 0;
            if (!isset($inventoryMap[$value['shopId']])){
                return ResultWrapper::fail('库存获取异常',ErrorCode::$paramError);
            }
            $row = $inventoryMap[$value['shopId']];
            $value['inventoryTotalNum'] = 0;
            foreach ($value['specMultiple'] as &$item){
                $item['inventoryNum'] = isset($row[$item['id']]['num']) ? $row[$item['id']]['num'] : 0;
                $item['ladderPriceMsg'] = '';
                $thisPrice = isset($priceMap[$value['shopId']][$value['id']]) ? $priceMap[$value['shopId']][$value['id']] : [];
                if (!empty($thisPrice)){
                    $item['salePrice'] = isset($thisPrice[$item['id']]) ? $thisPrice[$item['id']]['salePrice'] : '0.00';
                    $item['marketPrice'] = isset($thisPrice[$item['id']]) ? $thisPrice[$item['id']]['marketPrice'] : '0.00';
                    $item['ladderPrice'] = isset($thisPrice[$item['id']]) ? $thisPrice[$item['id']]['ladderPrice'] : [];
                }

                if (!empty($item['ladderPrice'])){
                    $str = '';
                    foreach ($item['ladderPrice'] as $v){
                        !empty($str) && $str .= ' ';
                        $str .= '('.$v['from'].'-'.$v['to'].')';
                        $str .= $v['price'];
                    }
                    $item['ladderPriceMsg'] = $str;
                }
            }

            $value['categoryName'] = isset($goodsBasicMap[$value['basicGoodsId']]) ? $goodsBasicMap[$value['basicGoodsId']]['categoryName'] : '无';
            $value['brandName'] = isset($goodsBasicMap[$value['basicGoodsId']]) ? $goodsBasicMap[$value['basicGoodsId']]['brandName'] : '无';
            $value['goodsName'] = isset($goodsBasicMap[$value['basicGoodsId']]) ? $goodsBasicMap[$value['basicGoodsId']]['title'] : '无';
            $value['goodsCode'] = createCode(StatusCode::$code['goodsBasic']['prefix'], $value['basicGoodsId'], StatusCode::$code['goodsBasic']['length']);;
            $value['enableStatusMsg'] = $value['enableStatus'] == StatusCode::$standard ? '上架' : '下架';
            $value['createTime'] = date('Y-m-d H:i:s',$value['createTime']);
            $value['tag'] = isset($goodsBasicMap[$value['basicGoodsId']]) ? $goodsBasicMap[$value['basicGoodsId']]['tag'] : '无';
            $value['describe'] = isset($goodsBasicMap[$value['basicGoodsId']]) ? $goodsBasicMap[$value['basicGoodsId']]['describe'] : '无';
            $value['storage'] = '无';
            if (isset($goodsBasicMap[$value['basicGoodsId']])){
                if (empty($goodsBasicMap[$value['basicGoodsId']]['extends'])){
                    $value['storage'] = empty($goodsBasicMap[$value['basicGoodsId']]['extends']) ?  '' : json_decode($goodsBasicMap[$value['basicGoodsId']]['extends'],true)['storage'];
                }
            }
            $value['salesTotalNum'] = 0;
            if (!empty($value['salesNum'])){
                $salesNum = json_decode($value['salesNum'],true);
                $value['salesTotalNum'] = array_sum(array_column($salesNum,'salesNum'));
            }
        }
        return ResultWrapper::success($data);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/8/25
     * Time: 11:50 上午
     * @param $selectParams
     * @throws Exception
     */
    public function fixEsData($selectParams)
    {
        $limit = $selectParams['limit'];
        unset($selectParams['limit']);
        $offset = $selectParams['offset'];
        unset($selectParams['offset']);
        $selectParams['deleteStatus'] = StatusCode::$standard;
        $dbResult = $this->objDGoods->select($selectParams, 'id', null, $limit, $offset);
        foreach ($dbResult as $goods) {
            self::updateEsData($goods['id']);
        }
        print_r(count($dbResult) . '条数据');
    }


    /**
     * 通过goodsIds获取名称
     * 注意：本方法并不能获取到商品名称，可用此方法拿到BasicGoodsId,再通过getNameByGoodsIds方法拿到商品名称
     * @param array $goodsIds
     * @param string $field
     * @return array
     * @throws Exception
     */
    public function getGoodsNames($goodsIds = [], $field = "*")
    {
        $return = [];
        if (!$goodsIds) {
            return $return;
        }

        $sql = 'select g.*,b.images from qianniao_goods_'.$this->enterpriseId.'  g left join qianniao_goods_basic_'.$this->enterpriseId.' b on g.basicGoodsId = b.id where g.id in ('.implode(',', $goodsIds).')';
        $goodsData = $this->objDGoods->query($sql);
        if ($goodsData === false) {
            return $return;
        }

        $supplierIds = [];
        foreach ($goodsData as $value){
            !empty($value['supplierId']) && $supplierIds[] = $value['supplierId'];
        }

        $supplierMap = [];
        $objMSupplier = new MSupplier($this->userCenterId,$this->enterpriseId);
        $supplierResult = $objMSupplier->getSupplierNameByIds($supplierIds);
        if ($supplierResult->isSuccess()){
            $supplier = $supplierResult->getData();
            $supplierMap = MSupplier::supplierMap($supplier);
        }


        foreach ($goodsData as &$goods) {
            $goods['supplierName'] = isset($supplierMap[$goods['supplierId']]['title']) ? $supplierMap[$goods['supplierId']]['title'] : '';
            $return[$goods['id']] = $goods;
        }
        return $return;
    }


    /**
     * 获取商品sku信息
     * @param $goodsBasic
     * @return array
     * @throws Exception
     */
    public function getGoodsBasicAndSkuInfo($goodsBasic)
    {
        $skuArray = [];//所有sku数组
        if (isset($goodsBasic['masterUnit']) && is_array($goodsBasic['masterUnit'])) {
            $goodsBasic['masterUnit']['skuId'] = $goodsBasic['masterUnit']['id'];
            unset($goodsBasic['masterUnit']['id']);
            $skuArray[] = $goodsBasic['masterUnit'];
        }
        if (isset($goodsBasic['branchUnit']) && is_array($goodsBasic['branchUnit'])) {
            $branchUnit = $goodsBasic['branchUnit'];
            foreach ($branchUnit as $branch) {
                $branch['skuId'] = $branch['id'];
                unset($branch['id']);
                $skuArray[] = $branch;
            }
        }
        return $skuArray;
    }

    /**
     * 处理销量
     * @param $goodsData
     * @param array $allGoodsIds
     * @return mixed
     * @throws Exception
     */
    public function getSalesNumBySku($goodsData, $allGoodsIds = [])
    {
        $cartData = [];
        if (!empty($allGoodsIds)) {
            $objMCart = new MCart($this->userCenterId, $this->enterpriseId);
            $cartData = $objMCart->getCartNumByGoodsId($allGoodsIds);
        }


        foreach ($goodsData as &$goods) {
            //[{"skuId":1,"salesNum":10},{"skuId":2,"salesNum":10}]  salesNum
            $salesNumArr = [];
            if (!empty($goods['salesNum'])) {
                $salesNumData = is_array($goods['salesNum']) ? $goods['salesNum'] : json_decode($goods['salesNum'], true);
                if ($salesNumData) {
                    foreach ($salesNumData as $salesNum) {
                        $salesNumArr[$salesNum['skuId']] = $salesNum['salesNum'];
                    }
                }
            }
            $goods['oldSalesNum'] = $goods['salesNum'];//复制原数据
            if(empty($goods['salesNum'])){
                $goods['salesNum'] = 0;
            }else{
                if(is_array($goods['salesNum'])){
                    $goods['salesNum'] = array_sum(array_column($goods['salesNum'],'salesNum'));
                }else{
                    $goods['salesNum'] = array_sum(array_column(json_decode($goods['salesNum'],true),'salesNum'));
                }
            }

            if (isset($goods['skuData'])) {
                foreach ($goods['skuData'] as &$goodsSku) {
                    $goodsSku['salesNum'] = isset($salesNumArr[$goodsSku['skuId']]) ? $salesNumArr[$goodsSku['skuId']] : 0;
                    //$goods['salesNum'] += $goodsSku['salesNum'];
                    $goodsSku['cartNum'] = isset($cartData[$goods['id']][$goodsSku['skuId']]) ? $cartData[$goods['id']][$goodsSku['skuId']] : 0;
                }
            }
        }
        return $goodsData;
    }

    /**
     * 处理价格
     * isActivityPrice 是否满足活动价 5:满足 4:不满足
     * salePrice 销售价格 小程序上展示的价格
     * marketPrice 市场价格
     * @param $goodsData
     * @return mixed
     * @throws Exception
     */
    public function getPriceBySku($goodsData)
    {

        foreach ($goodsData as &$goods) {
            foreach ($goods['skuData'] as &$goodsSku) {
                $goodsSku["salePrice"] = '';
                $goodsSku["ladderPrice"] = [];
                $goodsSku["marketPrice"] = '';
                $goodsSku["enabledLadder"] = '';
                $goodsSku['setNum'] = 0;//起订数量
                $goodsSku['isActivityPrice'] = StatusCode::$delete;//初始化,是否满足活动价
                $goodsSku['limitNum'] = 0;//活动商品限购数量
            }
        }
        unset($goods);
        //获取价格
        $selectParam['material'] = [];
        foreach ($goodsData as $goods) {
            $selectParam['material'][$goods['shopId']][] = $goods['id'];
        }

        if($this->userCenterId){
            $selectParam['customerId'] = $this->useCustomerId;//客户有特殊调价
        }

        $priceResult = $this->objMPrice->getPrice($selectParam);

        if (!$priceResult->isSuccess()) {
            return $goodsData;
        }

        $goodsArr = [];
        $priceResult = $priceResult->getData();
        foreach ($priceResult as $shopPriceArr) {
            foreach ($shopPriceArr as $goodsId => $goodsSkuArr) {
                $goodsArr[$goodsId] = $goodsSkuArr;
            }
        }

        //是否有营销活动价
        $objMCustomer = new MCustomer($this->enterpriseId, $this->userCenterId);
        $customerResult = $objMCustomer->getCustomerInfoByUserCenterId($this->userCenterId);
        $activityArr = [];
        if ($customerResult->isSuccess()) {
            $customer = $customerResult->getData();
            $objMActivity = new MActivity($this->userCenterId, $this->enterpriseId);
            //获取促销活动价格
            $dbResult = $objMActivity->getActivity([
                'goodsId'      => implode(',', array_column($goodsData, 'id')),
                'customerType' => isset($customer['type']) ? $customer['type'] : 0,
            ]);//TODO
            $activityResult = $dbResult->getData();
            unset($dbResult);
            foreach ($activityResult as $activity) {
                $activityArr[$activity['goodsId'] . $activity['skuId']] = $activity;
            }
        }

        foreach ($goodsData as &$goods) {
            if (isset($goodsArr[$goods['id']])) {
                $skuInfo = $goodsArr[$goods['id']];
                foreach ($goods['skuData'] as &$skuData) {
                    if (isset($skuInfo[$skuData['skuId']])) {
                        if (isset($activityArr[$goods['id'] . $skuData['skuId']])) {
                            //存在活动价格
                            $skuData["salePrice"] = $activityArr[$goods['id'] . $skuData['skuId']]['price'];
                            $skuData["activityId"] = $activityArr[$goods['id'] . $skuData['skuId']]['activityId'];//活动id
                            $skuData['isActivity'] = StatusCode::$standard;//活动价格
                            //如果用户登录,检测用户是否达到限购,商品是否枪光(是: 添加标识)
                            //获取用户活动购买数量
                            if (!empty($this->userCenterId)) {
                                $userLimit = (int)$this->objActivityLimitCache->getLimit($skuData["activityId"], $goods['id'], $skuData['skuId'], $this->userCenterId);
                                //活动商品用户限购数
                                $goodsLimit = (int)$activityArr[$goods['id'] . $skuData['skuId']]['limitNum'];
                                if ($userLimit < $goodsLimit) {
                                    //此商品相对用户,满足活动价
                                    $skuData['isActivityPrice'] = StatusCode::$standard;//满足活动价
                                }
                                $skuData['limitNum'] = $goodsLimit;
                            }
                        } else {
                            $skuData["salePrice"] = $skuInfo[$skuData['skuId']]['salePrice'];
                            $skuData["activityId"] = 0;//不存在活动
                        }
                        $skuData["isActivity"] = isset($skuData['isActivity']) ? $skuData['isActivity'] : StatusCode::$delete;
                        $skuData["originPrice"] = $skuInfo[$skuData['skuId']]['salePrice'];//原价(促销活动时价格有差异)
                        $skuData["ladderPrice"] = $skuInfo[$skuData['skuId']]['ladderPrice'];
                        $skuData["marketPrice"] = isset($skuInfo[$skuData['skuId']]['marketPrice']) ? $skuInfo[$skuData['skuId']]['marketPrice'] : bcadd($skuInfo[$skuData['skuId']]['salePrice'], mt_rand(1, 3), 2);
                        $skuData["enabledLadder"] = $skuInfo[$skuData['skuId']]['enabledLadder'];
                        if (isset($skuData['isActivity']) && $skuData['isActivity'] == StatusCode::$delete) {
                            $skuData["setNum"] = isset($skuInfo[$skuData['skuId']]['setNum']) ? $skuInfo[$skuData['skuId']]['setNum'] : 0;//起订数量
                        }
                    }
                }
            }
        }
        return $goodsData;
    }

    /**
     * Doc: (des="搜索的where条件拼接")
     * User: XMing
     * Date: 2020/11/30
     * Time: 10:53 上午
     * @param $selectParams
     * @param bool $export
     * @return array|ResultWrapper
     * @throws Exception
     */
    public function setWhere($selectParams,$export = false)
    {
        $defaultDSL = [];
        if($export === false){
            $defaultDSL = [
                'from' => $selectParams['offset'],
                'size' => $selectParams['limit'],
                'sort' => [
                    'topTime' => [
                        'order' => 'desc'
                    ]
                ],
            ];
        }


        $dsl = [];
        $dsl['query']['bool']['must'][] = [
            'term' => ['enterpriseId' => $this->enterpriseId],
        ];

        if (isset($selectParams['enableStatus'])) {
            if (!empty($selectParams['enableStatus'])) {
                $dsl['query']['bool']['filter'][] =
                    ['term' => ['enableStatus' => $selectParams['enableStatus']]];
            }
        }

        if (isset($selectParams['auditStatus'])) {
            if (!empty($selectParams['auditStatus'])) {
                $dsl['query']['bool']['filter'][] =
                    ['term' => ['auditStatus' => $selectParams['auditStatus']]];
            }
        }


        $selectParams = parent::getStaffQueryParams($selectParams, 'staffId');
        //个人数据域
        if (isset($selectParams['staffId'])) {
            $dsl['query']['bool']['filter'][] =
                ['terms' => ['staffId' => $selectParams['staffId']]];
        }

        //按商品ids进行搜索
        if (isset($selectParams['goodsIds'])) {
            $dsl['query']['bool']['filter'][] =
                ['terms' => ['id' => $selectParams['goodsIds']]];
        }

        //去ES的basic类型下查找匹配的basicIds
        if (!empty($selectParams['keyword'])
            || !empty($selectParams['categoryId'])
            || !empty($selectParams['brandId'])
            || !empty($selectParams['categoryPath'])
        ) {
            $basicSearchParams = [
                'keyword'    => isset($selectParams['keyword']) ? $selectParams['keyword'] : '',
                'categoryPath' => isset($selectParams['categoryPath']) ? $selectParams['categoryPath'] : '',
                'categoryId' => isset($selectParams['categoryId']) ? $selectParams['categoryId'] : '',
                'brandId'    => isset($selectParams['brandId']) ? $selectParams['brandId'] : '',
                'limit'      => 1000
            ];

            $goodsBasics = $this->objMGoodsBasic->searchGoodsBasics($basicSearchParams);

            $goodsBasicLists = [];
            if (!$goodsBasics->isSuccess()) {
                Logger::logs(E_USER_ERROR,'es-查询错误',__CLASS__,__LINE__,$goodsBasics->getData());
                return ResultWrapper::fail($goodsBasics->getData(),$goodsBasics->getErrorCode());
            } else {
                $goodsBasicData = $goodsBasics->getData();
                foreach ($goodsBasicData as $goodsBasic) {
                    $goodsBasicLists[$goodsBasic['id']] = $goodsBasic;
                }
            }
            $goodsBasicIds = array_keys($goodsBasicLists);
            $dsl['query']['bool']['must'][] = [
                'terms' => [
                    'basicGoodsId' => $goodsBasicIds
                ]
            ];
        }

        //后台按商铺搜索
        if (!empty($selectParams['shopId'])) {
            if (is_array($selectParams['shopId'])) {
                $dsl['query']['bool']['must'][] = [
                    'terms' => [
                        'shopId' => $selectParams['shopId']
                    ]
                ];
            } else {
                $dsl['query']['bool']['must'][] = [
                    'term' => [
                        'shopId' => $selectParams['shopId']
                    ],
                ];
            }
        }


        //前台按销售区域筛选
        if ($this->isFront) {
            $dsl['query']['bool']['must'][] = [
                'term' => ['enableStatus' => StatusCode::$standard],
            ];
            $areaCode = isset($selectParams['areaCode']) ? $selectParams['areaCode'] : '';
            $shopIdResult = $this->objMShop->getShopIdsByArea($selectParams['userCenterId'], $areaCode);
            if (!$shopIdResult->isSuccess()) {
                Logger::logs(E_USER_ERROR,'es-查询错误',__CLASS__,__LINE__,$shopIdResult->getData());
                return ResultWrapper::fail($shopIdResult->getData(),$shopIdResult->getErrorCode());
            }
            $shopIds = $shopIdResult->getData();
            /*$dsl['query']['bool']['must'][] = [
                'terms' => [
                    'shopId' => $shopIds
                ]
            ];*/
        } else {
            //数据域
            /*parent::getAccessShopIds();
            if (!empty(parent::$shopIds)) {
                $dsl['query']['bool']['filter'][] = [
                    'terms' => ['shopId' => parent::$shopIds]
                ];
            }*/
        }

        if (isset($selectParams['inStock'])) {
            $goodsBasicIdResult = self::getInOrOutOfStockGoodsBasicId($selectParams['inStock']);
            if (!$goodsBasicIdResult->isSuccess()) {
                Logger::logs(E_USER_ERROR,'es-查询错误',__CLASS__,__LINE__,$goodsBasicIdResult->getData());
                return ResultWrapper::fail($goodsBasicIdResult->getData(),$goodsBasicIdResult->getErrorCode());
            }
        }
        $dsl = array_merge($defaultDSL, $dsl);
        return ResultWrapper::success($dsl);
    }

    /**
     *
     * 废弃
     * @param $inStock
     * @return ResultWrapper
     */
    //获取有无库存的基本资料id
    public function getInOrOutOfStockGoodsBasicId($inStock)
    {

        //查询所有商品获取库存
        $lists = $this->objDGoods->query('SELECT `id`,`shopId`,`basicGoodsId` FROM qianniao_goods_'.$this->enterpriseId.' WHERE `deleteStatus` = '.StatusCode::$standard);
        if ($lists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        if (empty($lists)){
            return ResultWrapper::success([]);
        }
        $selectParams = [];
        foreach ($lists as $list){
            $selectParams[$list['shopId']][] = $list['basicGoodsId'];
        }
        //查询库存
        $inventoryMap = [];
        $objMInventory = new MInventory($this->enterpriseId,$this->userCenterId);
        foreach ($selectParams as $shopId => $materielIds){
            // 根据商铺id和物料ids获取库存信息
            $inventoryResult = $objMInventory->getInventoryByShopIdAndMaterielIds($shopId,$materielIds);
            if (!$inventoryResult->isSuccess()){
                return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
            }
            $inventory = $inventoryResult->getData();
            foreach ($inventory as $id => $item){
                if ($inStock == StatusCode::$standard){
                    $item['num'] > 0 && $inventoryMap[] = [
                        'shopId' => $shopId,
                        'basicGoodsId' => $id
                    ];
                }else{
                    $item['num'] == 0 && $inventoryMap[] = [
                        'shopId' => $shopId,
                        'basicGoodsId' => $id
                    ];
                }
            }
        }
        return ResultWrapper::success($inventoryMap);
    }

    /**
     * 创建订单搜索商品 首字母搜索
     * @param $data
     * @param bool $type
     * @return ResultWrapper
     */
    public function getGoodsByCondition($data, $type = false)
    {
        $Condition = isset($data['condition']) && !empty($data['condition']) ? $data['condition'] : '';
        if (empty($Condition)) return ResultWrapper::success([]);
        $objChineseCharacter = new ChineseCharacter();
        $Condition = $objChineseCharacter->getInitials($Condition);
        $objDGoodsBasic = new DGoodsBasic();

        //判断是否上架 没有参数默认查询所有
        $whereSql = '';
        if (isset($data['enableStatus']) && !empty($data['enableStatus'])) {
            $whereSql .= ' and g.enableStatus = ' . $data['enableStatus'];
        }
        //判断是否有商铺检索
        if(isset($data['shopId']) && !empty($data['shopId'])){
            if(is_array($data['shopId'])){
                $str = 'in('.rtrim(implode(',',$data['shopId']),',').')';
            }else{
                $str = '= '.$data['shopId'];
            }
            $whereSql .= ' and g.shopId '.$str;
        }

        //查询商品sql
        $sql = 'select g.id,b.title from ' . $this->objDGoods->get_Table() . ' g left join ' . $objDGoodsBasic->get_Table() . '_' . $this->enterpriseId . ' b on g.basicGoodsId = b.id where b.condition like "%' . $Condition . '%" and g.deleteStatus = ' . StatusCode::$standard . $whereSql . ' order by g.id desc';
        //判断来源 false查询商品 true查询基础资料
        if ($type) {
            //查询基础资料sql
            $sql = 'select id,title from ' . $objDGoodsBasic->get_Table() . '_' . $this->enterpriseId . ' where `condition` like "%' . $Condition . '%" and deleteStatus = ' . StatusCode::$standard . ' order by id desc';
        }

        $dbResult = $this->objDGoods->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }

        return ResultWrapper::success($dbResult);
    }

    /**
     * 格式化所有商品搜索条件
     * @param $enterpriseId
     * @return ResultWrapper
     * @throws Exception
     */
    public function formatGoodsCondition($enterpriseId)
    {
        $objDGoodsBasic = new DGoodsBasic();
        $objDGoodsBasic->setTable($objDGoodsBasic->get_Table() . '_' . $enterpriseId);
        $sql = 'select id,title from ' . $objDGoodsBasic->get_Table();
        $dbResult = $objDGoodsBasic->query($sql);
        if ($dbResult === false) {
            return ResultWrapper::fail($objDGoodsBasic->error(), ErrorCode::$dberror);
        }
        $objChineseCharacter = new ChineseCharacter();
        foreach ($dbResult as $value) {
            $Condition = $objChineseCharacter->getInitials(trim($value['title']));
            $midDbResult = $objDGoodsBasic->update(['condition' => $Condition], ['id' => $value['id']]);
            if ($midDbResult === false) {
                return ResultWrapper::fail($objDGoodsBasic->error(), ErrorCode::$dberror);
            }
        }
        return ResultWrapper::success('格式化成功');
    }

    /**
     * Doc: (des="根据条件查询商品")
     * User: XMing
     * Date: 2020/11/30
     * Time: 11:00 上午
     * @param string $keyword
     * @return ResultWrapper
     * @throws Exception
     */
    private function searchByKeyword(string $keyword)
    {
        //如果是关键词搜索，尝试从es中检索商品
        $dslResult = $this->setWhere(['keyword'=>$keyword,'offset' => 0,'limit' => 10,'userCenterId' => $this->userCenterId]);
        if (!$dslResult->isSuccess()){
            return ResultWrapper::fail($dslResult->getData(),$dslResult->getErrorCode());
        }
        $dsl = $dslResult->getData();
        $result = $this->objDGoods->getSearchQueryDsl($dsl);
        if (isset($result['status']) && $result['status'] == 400) {
            if ($result['error']['reason'] == 'all shards failed') {
                return ResultWrapper::success([
                    'data'  => [],
                    'total' => 0
                ]);
            }
        }
        if (!isset($result['hits']) || $result['hits']['total'] == 0) {
            return ResultWrapper::success([
                'data'  => [],
                'total' => 0
            ]);
        }
        $esLists = $result['hits']['hits'];
        $allGoodsIds = [];
        foreach ($esLists as $key => &$value) {
            //$data['id'] = $value['_id'];
            $allGoodsIds[] = $value['_source']['id'];
        }
        $goodsResult = self::getGoodsBySelectParams(['goodsIds' => $allGoodsIds,'offset' => 0,'limit' => 10],true);
        if (!$goodsResult->isSuccess()){
            return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
        }
        $goodsResult = $goodsResult->getData();
        $total = $goodsResult['total'];
        $goodsData = $goodsResult['data'];
        return ResultWrapper::success(['data'=>$goodsData,'total' => $total]);
    }


    /**
     * Doc: (des="根据条件查询过滤商品id")
     * User: XMing
     * Date: 2021/1/18
     * Time: 10:27 上午
     * @param array $selectParams
     * @return ResultWrapper
     * @throws Exception
     */
    public function getFilterIdsBySelectParams(array $selectParams): ResultWrapper
    {
        $retIds = [];
        if (isset($selectParams['userCenterId']) && !empty($selectParams['userCenterId'])){
            //通过userCenterId获取客户id以及客户类型
            $customerResult = $this->objMCustomer->getCustomerInfoByUserCenterId($selectParams['userCenterId']);
            if (!$customerResult->isSuccess()){
                return ResultWrapper::fail($customerResult->getData(),$customerResult->getErrorCode());
            }
            $customerInfo = $customerResult->getData();
            $customerId = getArrayItem($customerInfo,'id',0);
            $customerType = getArrayItem($customerInfo,'type',0);

            $filter = '';
            if (isset($customerId) && !empty($customerId)){
                $filter .= ' FIND_IN_SET('.$customerId.',`notCustomer`) ';
                if (isset($customerType) && !empty($customerType)){
                    $filter .= ' OR FIND_IN_SET('.$customerType.',`notCustomerType`) ';
                }
            }
            if (isset($selectParams['areaCode']) && !empty($selectParams['areaCode'])){
                $areaCode = $selectParams['areaCode'];
                if (!empty($filter)){
                    $filter .= ' OR ';
                }
                $filter .= " (JSON_CONTAINS(notArea->'$[*]', '\"".$areaCode."\"', '$') OR JSON_CONTAINS(notArea->'$[*]','\"0-0-0\"','$')) ";
            }
            $fields = 'id';
            $sql = 'SELECT '.$fields.' FROM qianniao_goods_'.$this->enterpriseId.' WHERE isShield = '.StatusCode::$standard.' AND ( '.$filter.')';

            $ids = $this->objDGoods->query($sql);
            if ($ids === false){
                return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
            }
            foreach ($ids as $val){
                $retIds[] = $val['id'];
            }
        }
        return ResultWrapper::success($retIds);
    }

    /**
     * Doc: (des="商品检索 商城、后台")
     * User: XMing
     * Date: 2021/3/3
     * Time: 3:21 下午
     * @param array $selectParams
     * @param bool $export
     * @return ResultWrapper
     * @version 1.0.1
     */
    public function search_new(array $selectParams,bool $export = false): ResultWrapper
    {
        switch ($this->isFront){
            case true:
                //mini app
                //1.获取当前范围内的店铺
                $shopResult = self::getShopIdsByArea($selectParams['areaCode']);
                if (!$shopResult->isSuccess()){
                    return ResultWrapper::fail($shopResult->getData(),ErrorCode::$dberror);
                }
                $shopData = $shopResult->getData();
                if (empty($shopData)){
                    return ResultWrapper::success(['data'  => [], 'total' => 0]);
                }
                $shopIds = isset($shopData['shopIds']) ? $shopData['shopIds'] : [];
                //商品查询参数
                $condition = [
                    'shopId'        => isset($selectParams['shopId']) ? $selectParams['shopId'] : 0,
                    'shopIds'       => $shopIds,
                    'categoryId'    => isset($selectParams['categoryId']) ? $selectParams['categoryId'] : '',
                    'keyword'       => isset($selectParams['keyword']) ? $selectParams['keyword'] : '',
                    'goodsIds'      => isset($selectParams['goodsIds']) ? $selectParams['goodsIds'] : [],
                    'categoryPath'  => isset($selectParams['categoryPath']) ? $selectParams['categoryPath'] : [],
                    'offset'        => $selectParams['offset'],
                    'limit'         => $selectParams['limit']
                ];
                //查询店铺下经营屏蔽的商品Id
                $filterIdsResult = self::getFilterIdsBySelectParams($selectParams);
                if (!$filterIdsResult->isSuccess()){
                    return ResultWrapper::fail($filterIdsResult->getData(),$filterIdsResult->getErrorCode());
                }
                //过滤商品ids
                $filterIds = $filterIdsResult->getData();
                $condition['notGoodsIds'] = $filterIds;


                break;
            case false:
                //manage

                break;
        }
    }

    /**
     * Doc: (des="es-搜索商品")
     * User: XMing
     * Date: 2020/11/30
     * Time: 10:40 上午
     * @param array $selectParams 搜索条件
     * @param bool $export 是否导出
     * @return ResultWrapper
     * @throws Exception
     */
    public function search(array $selectParams,$export = false)
    {

        if($this->isFront){
            $shopResult = self::getShopIdsByArea($selectParams['areaCode']);
            if (!$shopResult->isSuccess()){
                return ResultWrapper::fail($shopResult->getData(),ErrorCode::$dberror);
            }
            $shopData = $shopResult->getData();//销售区域店铺数据
            if (empty($shopData)){
                return ResultWrapper::success(['data'  => [], 'total' => 0]);
            }

            $shopIds = isset($shopData['shopIds']) ? $shopData['shopIds'] : [];
            //条件
            $condition = [
                'shopId' => isset($selectParams['shopId']) ? $selectParams['shopId'] : 0,
                'shopIds' => $shopIds,
                'categoryId'=> isset($selectParams['categoryId']) ? $selectParams['categoryId'] : '',
                'keyword'  => isset($selectParams['keyword']) ? $selectParams['keyword'] : '',
                'goodsIds' => isset($selectParams['goodsIds']) ? $selectParams['goodsIds'] : [],
                'categoryPath' => isset($selectParams['categoryPath']) ? $selectParams['categoryPath'] : [],
                'offset'   => $selectParams['offset'],
                'limit'    => $selectParams['limit'],
                'brandId'    => isset($selectParams['brandId']) ? $selectParams['brandId'] : [],//商品品牌
                'sort'          => isset($selectParams['sort']) ? $selectParams['sort'] : '',           //销售排序
                'priceSort'     => isset($selectParams['priceSort']) ? $selectParams['priceSort'] : '',  //价格排序
                'support'     => isset($selectParams['support']) ? $selectParams['support'] : [],  //商品服务
                'goodsGroups'     => isset($selectParams['goodsGroups']) ? $selectParams['goodsGroups'] : '',  //商品分组
                'enableStatus'    => getArrayItem($selectParams, 'enableStatus', 5),
            ];
            // 通过区域获取销售店铺
            $filterIdsResult = self::getFilterIdsBySelectParams($selectParams);
            if (!$filterIdsResult->isSuccess()){
                return ResultWrapper::fail($filterIdsResult->getData(),$filterIdsResult->getErrorCode());
            }
            $filterIds = $filterIdsResult->getData();
            $condition['notGoodsIds'] = $filterIds;//过滤商品id
            $goodsResult = self::getGoodsBySelectParams($condition,true);
            if (!$goodsResult->isSuccess()){
                return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
            }
            $goodsResult = $goodsResult->getData();
            $total = $goodsResult['total'];
            $goodsData = $goodsResult['data'];
            if (empty($total)){
                if (isset($condition['keyword']) && !empty($condition['keyword'])){
                    $searchResult = self::searchByKeyword($condition['keyword']);
                    if (!$searchResult->isSuccess()){
                        return ResultWrapper::fail($searchResult->getData(),$searchResult->getErrorCode());
                    }
                    $searchData = $searchResult->getData();
                    $total = $searchData['total'];
                    $goodsData = $searchData['data'];
                    if (empty($goodsData)){
                        return ResultWrapper::success(['data'  => [], 'total' => 0]);
                    }
                }
            }

            // 商品数据/最高最低价格
            $formatGoodsRes = self::formatGoodsData($goodsData,$shopData['shopIdBindWarehouseId']);
            if (!$formatGoodsRes->isSuccess()){
                return ResultWrapper::fail($formatGoodsRes->getData(),$formatGoodsRes->getErrorCode());
            }
            $goodsData = $formatGoodsRes->getData();
            $return = [
                'data'  => self::formatJsonGoods($goodsData),
                'total' => $total,
            ];
        }else{
            $searchResult = self::searchManage($selectParams,$export);
            if (!$searchResult->isSuccess()){
                return ResultWrapper::fail($searchResult->getData(),$searchResult->getErrorCode());
            }
            $return = $searchResult->getData();
        }

        return ResultWrapper::success($return);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/1/23
     * Time: 3:57 下午
     * @param array $selectParams
     * @param bool $export
     * @return ResultWrapper
     * @throws Exception
     */
    public function searchManage(array $selectParams,$export = false): ResultWrapper
    {
        $goodsResult = self::getGoodsBySelectParams($selectParams,true);
        if (!$goodsResult->isSuccess()){
            return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
        }
        $goodsResult = $goodsResult->getData();
        $total = $goodsResult['total'];
        $goodsData = $goodsResult['data'];
        if($export === true){
            $result =  self::exportGoods($selectParams,'db');
            if(!$result->isSuccess()){
                return ResultWrapper::fail($result->getData(), $result->getErrorCode());
            }
            die;
        }
        if (empty($goodsData)){
            return ResultWrapper::success(['data'  => [], 'total' => 0]);
        }

        $formatResult = self::formatManageGoodsLists($goodsData);
        if (!$formatResult->isSuccess()){
            return ResultWrapper::fail($formatResult->getData(),$formatResult->getErrorCode());
        }
        $return = [
            'data'  => $formatResult->getData(),
            'total' => ($total) ? intval($total) : 0,
        ];
        return ResultWrapper::success($return);
    }

    /**
     * 统一的格式化商品列表数据
     * @param array $goodsData 商品主数据
     * @return ResultWrapper
     */
    private function formatManageGoodsLists(array $goodsData)
    {
        if (empty($goodsData)){
            return ResultWrapper::success([]);
        }

        $basicGoodsIds = []; // 所有商品资料ids
        $shopIds = [];       // 店铺ids
        $merchantIds = [];    // 商户ids
        $selectInventorParams = []; // 查询库存

        foreach($goodsData as $key => $value){
            $basicGoodsIds[] = $value['basicGoodsId'];
            $shopIds[] = $value['shopId'];
            $merchantIds[] = $value['merchantId'];
            $selectInventorParams[$value['shopId']][] = $value['basicGoodsId'];
        }

        // 获取商品库数据
        $basicGodsBind = [];
        $materielResult = $this->objMGoodsBasic->getGoodsBasicNames(array_unique($basicGoodsIds));
        if (!$materielResult->isSuccess()){
            return ResultWrapper::fail($materielResult->getData(),$materielResult->getErrorCode());
        }
        $materielMap = $materielResult->getData();
        if(!empty($materielMap)){
            $materielMapResult = $this->objMGoodsBasic->formatMaterielLists($materielMap);
            if (!$materielMapResult->isSuccess()){
                return ResultWrapper::fail($materielMapResult->getData(),$materielMapResult->getErrorCode());
            }
            $materielMap = $materielMapResult->getData();
            foreach($materielMap as $key => $value){
                $basicGodsBind[$value['id']] = $value;
            }
        }

        // 店铺数据映射
        $shopMap = [];
        if (!empty($shopIds)){
            $shopResult = $this->objMShop->getShopByIds(array_unique($shopIds));
            if (!$shopResult->isSuccess()){
                return ResultWrapper::fail($shopResult->getData(),$shopResult->getErrorCode());
            }
            $shopData = $shopResult->getData();
            if(!empty($shopData)){
                foreach($shopData as $key => $value){
                    $shopMap[$value['id']] = $value;
                }
            }
        }

        // 商户数据映射
        $merchantIds = array_filter($merchantIds);
        if(!empty($merchantIds)){
            $objMMerchant = new MMerchant($this->enterpriseId);
            $merchantData = $objMMerchant->getMerchant($merchantIds);
        }


        //查询库存
        $inventoryMap = [];
        foreach ($selectInventorParams as $shopId => $materielIds){
            $inventoryResult = $this->objMInventory->getInventoryByShopIdAndMaterielIds($shopId,$materielIds);
            if (!$inventoryResult->isSuccess()){
                return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
            }
            $inventoryMap[$shopId] = $inventoryResult->getData();
        }

        $objGoodsBasicRelevantCache = new GoodsBasicRelevant($this->enterpriseId);

        // 统一拿商品资料数据去覆盖商品列表的字段
        foreach($goodsData as $key => $value){
            $goodsData[$key]['code']   = createCode(StatusCode::$code['goodsBasic']['prefix'], $value['basicGoodsId'], StatusCode::$code['goodsBasic']['length']);
            $goodsData[$key]['images'] = isset($basicGodsBind[$value['basicGoodsId']]['images']) ? json_decode($basicGodsBind[$value['basicGoodsId']]['images'], true) : [];
            $goodsData[$key]['title']  = $basicGodsBind[$value['basicGoodsId']]['title'];
            $goodsData[$key]['barCode']  = $basicGodsBind[$value['basicGoodsId']]['barCode'];
            $goodsData[$key]['unitNameMaster']   = $basicGodsBind[$value['basicGoodsId']]['unitNameMaster'];
            $goodsData[$key]['isEq']   = $basicGodsBind[$value['basicGoodsId']]['isEq'];
            $goodsData[$key]['specType']   = $basicGodsBind[$value['basicGoodsId']]['specType'];
            $goodsData[$key]['specGroup'] =  $basicGodsBind[$value['basicGoodsId']]['specGroup'];
            $goodsData[$key]['specTotal']   = $basicGodsBind[$value['basicGoodsId']]['specTotal'];
            $goodsData[$key]['categoryName']  = $basicGodsBind[$value['basicGoodsId']]['categoryTitle'];
            $goodsData[$key]['categoryId']  = $basicGodsBind[$value['basicGoodsId']]['categoryId'];
            $goodsData[$key]['categoryPath']  = $basicGodsBind[$value['basicGoodsId']]['categoryPath'];
            $goodsData[$key]['assistCategoryName']  = $basicGodsBind[$value['basicGoodsId']]['assistCategoryTitle'];
            $goodsData[$key]['assistCategoryId']  = $basicGodsBind[$value['basicGoodsId']]['assistCategoryId'];
            $goodsData[$key]['assistCategoryPath']  = $basicGodsBind[$value['basicGoodsId']]['assistCategoryPath'];
            $goodsData[$key]['tag'] = explode(',', getArrayItem($basicGodsBind[$value['basicGoodsId']],'tag',''));
            $goodsData[$key]['brandId'] = $basicGodsBind[$value['basicGoodsId']]['brandId'];
            $goodsData[$key]['brandName'] = $basicGodsBind[$value['basicGoodsId']]['brandTitle'];

            $goodsData[$key]['shopName']  = isset($shopMap[$value['shopId']]) ? $shopMap[$value['shopId']]['name'] : '';
            $goodsData[$key]['inventorTotal'] = isset($inventoryMap[$value['shopId']][$value['basicGoodsId']]['num']) ? $inventoryMap[$value['shopId']][$value['basicGoodsId']]['num'] : 0;
            $goodsData[$key]['goodsGroups'] = !empty($value['goodsGroups']) ? explode(',',$value['goodsGroups']) : [];
            $goodsData[$key]['support'] = !empty($value['support']) ? explode(',',$value['support']) : [];



            if(isset($value['merchantId'])){
                $goodsData[$key]['merchantName'] = isset($merchantData[$value['merchantId']]) ? $merchantData[$value['merchantId']]['name'] : '';
            }
            // 对详情反转义
            if (isset($value['content'])) {
                $goodsData[$key]['content'] = htmlspecialchars_decode($value['content'], ENT_QUOTES);
            }

            $goodsData[$key]['oldSalesNum']  = getArrayItem($value,'salesNum',[]);
            $salesNumArray = (array)json_decode(getArrayItem($value,'salesNum',''),true);
            $goodsData[$key]['salesNum']  = array_sum(array_column($salesNumArray,'salesNum'));
        }
        
        return ResultWrapper::success($goodsData);
    }

    /**
     * 商品详情拼接数据
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public function formatDetails(array $data): ResultWrapper
    {
        if (empty($data)) {
            return ResultWrapper::success([]);
        }
        $formatMultipleResult = self::formatMultipleSkuMapping($data, StatusCode::$standard);//处理属性
        if (!$formatMultipleResult->isSuccess()){
            return ResultWrapper::fail($formatMultipleResult->getData(),$formatMultipleResult->getErrorCode());
        }
        $formatMultiple = $formatMultipleResult->getData();

        $initDetails = self::formatInitSpec($formatMultiple);//初始化数据
        $formatInventoryResult = self::formatInventorySpec($initDetails);//查询库存
        if (!$formatInventoryResult->isSuccess()){
            return ResultWrapper::fail($formatInventoryResult->getData(),$formatInventoryResult->getErrorCode());
        }
        $formatInventory = $formatInventoryResult->getData();

        // 处理价格
        $priceResult = self::getPriceBySkuSpec([$formatInventory]);
        if (!$priceResult->isSuccess()){
            return ResultWrapper::fail($priceResult->getData(),$priceResult->getErrorCode());
        }
        $priceData = $priceResult->getData();
        $data = self::getSalesNumDetails($priceData);//拼接销量(详情)
        $data = self::formatGoodsSpec($data);//提取字段
        $data = array_shift($data);
        return ResultWrapper::success($data);
    }

    /**
     * Doc: (des="格式化客户屏蔽列表")
     * User: XMing
     * Date: 2021/1/15
     * Time: 5:07 下午
     * @return ResultWrapper
     * @throws Exception
     */
    public function formatNotCustomer($data): ResultWrapper
    {
        if (empty($data)){
            return ResultWrapper::success($data);
        }

        $data['notCustomerLists'] = [];
        if ($data['isShield'] == StatusCode::$standard){
            $notCustomer = getArrayItem($data,'notCustomer','');
            if (empty($notCustomer)){
                $data['notCustomerLists'] = [];
                return ResultWrapper::success($data);
            }

            $notCustomerArr = explode(',',$notCustomer);
            $objMCustomer = new MCustomer($this->enterpriseId,$this->userCenterId);

            $customerListsResult = $objMCustomer->getCustomerByIds($notCustomerArr);
            if (!$customerListsResult->isSuccess()){
                return ResultWrapper::fail($customerListsResult->getData(),$customerListsResult->getErrorCode());
            }
            $customerLists = $customerListsResult->getData();
            foreach ($customerLists as $val){
                $data['notCustomerLists'][] = [
                    'id' => $val['id'],
                    'code' => $val['code'],
                    'customerType' => $val['customerType'],
                    'mobile' => $val['mobile'],
                    'name'   => $val['name'],
                    'status' => $val['status'],
                    'shopName' => $val['shopName']
                ];
            }

        }
        return ResultWrapper::success($data);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/9/10
     * Time: 11:55 上午
     * @throws Exception
     */
    private function formatGoodsExpress(array $data)
    {
        $data['express'] = [
            'expressType' => $data['expressType'],
            'ruleId'      => $data['ruleId'],
            'expressFee'  => $data['expressFee'],
            'showExpress' => $data['showExpress'],
            'ruleData'    => [
                'not_dispatch_areas' => (object)[]
            ],
        ];

        $ruleInfo = [];
        if ($data['expressType'] == StatusCode::$expressType['rule']){
            $objMDeliverySetting = new MDeliverySetting($this->userCenterId,$this->enterpriseId);
            $ruleInfoResult = $objMDeliverySetting->getRuleInfo($data['express']['ruleId']);
            if (!$ruleInfoResult->isSuccess()){
                return ResultWrapper::fail($ruleInfoResult->getData(),$ruleInfoResult->getErrorCode());
            }
            $ruleInfo = $ruleInfoResult->getData();
        }
        $data['express']['ruleData']['not_dispatch_areas'] = isset($ruleInfo['setData']) ? $ruleInfo['setData']['not_dispatch_areas'] : (object)[];
        return ResultWrapper::success($data);
    }

    /**
     * @param $data
     * @param $isAddGoods
     * @return mixed
     * @throws \Exception
     */
    public function formatMultipleSkuMapping($data, $isAddGoods = 4): ResultWrapper
    {
        switch ($isAddGoods) {
            case StatusCode::$standard:
                $sql = "SELECT id,unitId,unitName,conversion,isDefault,isMaster,specGroupHash,specImage,specData,barCode,weight,isNew FROM qianniao_sku_" . $this->enterpriseId . " WHERE goodsId=" . $data['basicGoodsId'] . " AND deleteStatus=" . StatusCode::$standard;
                break;
            case StatusCode::$delete:
                $sql = "SELECT id,unitId,unitName,conversion,isDefault,isMaster,specGroupHash,specImage,specData,barCode,weight,isNew FROM qianniao_sku_" . $this->enterpriseId . " WHERE goodsId=" . $data['basicGoodsId'] . " AND deleteStatus=" . StatusCode::$standard . " AND isMaster=" . StatusCode::$standard . " GROUP BY specGroupHash";
                break;
        }

        $skuResult = $this->objMSku->getQuery($sql);
        if (!$skuResult->isSuccess()){
            return ResultWrapper::fail($skuResult->getData(),$skuResult->getErrorCode());
        }
        $skuData = $skuResult->getData();

        $specMultiple = [];
        foreach ($skuData as $spec) {
            $specGroup = json_decode($spec['specData'], true);
            $specMultiple[] = [
                'id'            => $spec['id'],
                'unitId'        => $spec['unitId'],
                'unitName'      => $spec['unitName'],
                'isMaster'      => $spec['isMaster'],
                'conversion'    => $spec['conversion'],
                'specGroup'     => empty($specGroup) ? [] : $specGroup,
                'specGroupHash' => $spec['specGroupHash'],
                'specImage'     => empty(json_decode($spec['specImage'], true)) ? '' : json_decode($spec['specImage'], true),
                'barCode'       => empty($spec['barCode']) ? '' : $spec['barCode'],
                'isDefault'     => $spec['isDefault'],
                'weight'        => $spec['weight'],
                'isNew'         => $spec['isNew']
            ];
        }

        $data['specMultiple'] = $specMultiple;
        return ResultWrapper::success($data);
    }


    /**
     * 查询基础商品对应规格数量
     * @param $data
     * @return array
     */
    public function getSpecTotal(array $data): ResultWrapper
    {
        $goodsIds = array_values(array_unique(array_column($data, 'basicGoodsId')));
        $goodsIds = trim(implode(',', $goodsIds), ',');
        if (empty($goodsIds)){
            return ResultWrapper::success([]);
        }
        $sql = 'SELECT COUNT(id) as total,goodsId FROM qianniao_sku_' . $this->enterpriseId . ' WHERE deleteStatus = ' . StatusCode::$standard . ' AND goodsId IN(' . $goodsIds . ') GROUP BY goodsId;';
        $dbResult = $this->objMSku->getQuery($sql);
        if (!$dbResult->isSuccess()) {
            Logger::logs(E_USER_ERROR,'sql error',__CLASS__,__LINE__,$dbResult->getData());
        }
        $allSpec = $dbResult->getData();
        $mapping = [];
        foreach ($allSpec as $spec) {
            $mapping[$spec['goodsId']] = $spec['total'];
        }
        return ResultWrapper::success($mapping);
    }

    /**
     * @param $data
     * @return mixed
     */
    public function formatGoodsSpec($data)
    {
        if (empty($data)) {
            return $data;
        }
        $objMSku = new MSku($this->userCenterId,$this->enterpriseId);
        foreach ($data as &$details) {
            $details['minSalePrice'] = empty($this->commonMapping[$details['id']]) ? 0 : min($this->commonMapping[$details['id']]);
            $details['maxSalePrice'] = empty($this->commonMapping[$details['id']]) ? 0 : max($this->commonMapping[$details['id']]);
            unset($details['oldSalesNum']);

            if (isset($details['specGroup']) && !empty($details['specGroup'])) {
                $details['specGroup'] = is_array($details['specGroup']) ? $details['specGroup'] : json_decode($details['specGroup'], true);
            }


            //生成规格唯一索引
            $specMultiple = $details['specMultiple'];
            if (empty($specMultiple)) {
                continue;
            }
            if (!isset($details['salesNum']) || !is_numeric($details['salesNum'])){
                $details['salesNum'] = 0;
            }
            $details['salePrice'] = isset($specMultiple[0]['salePrice']) ? $specMultiple[0]['salePrice'] : 0;
            $details['setNum'] = isset($specMultiple[0]['setNum']) ? $specMultiple[0]['setNum'] : 0;
            $details['inventory'] = isset($specMultiple[0]['inventory']) ? $specMultiple[0]['inventory'] : 0;
            $details['unitName'] = isset($specMultiple[0]['unitName']) ? $specMultiple[0]['unitName'] : 0;
            if(!isset($details['marketPrice'])){
                $details['marketPrice'] = isset($specMultiple[0]['marketPrice']) ? $specMultiple[0]['marketPrice'] : 0;
            }

            foreach ($specMultiple as &$spec) {
                $index = $details['id'] . ':' . $spec['unitId'];//商品ID
                //$subName = '';
                if (!empty($spec['specGroup'])) {
                    foreach ($spec['specGroup'] as $row) {
                        $index .= empty($index) ? $row['specValueId'] : ':' . $row['specValueId'];
                    }
                }
                $spec['index'] = $index;
                $spec['indexGroup'] = explode(':', $index);
                //$spec['subName'] = $subName;
            }
            $details['specMultiple'] = $specMultiple;
            $details['notArea'] = empty($details['notArea']) ? [] : json_decode($details['notArea'],true);

            $sql = "SELECT id,barCode,unitId,unitName,conversion,isMaster,barCode,specType,isDefault,`weight`,isNew FROM qianniao_sku_" . $this->enterpriseId . " WHERE goodsId=" . $details['basicGoodsId'] . " AND deleteStatus=" . StatusCode::$standard . " ORDER BY isMaster DESC";

            $skuResult = $objMSku->getQuery($sql);
            $skuData = [];
            if ($skuResult->isSuccess()) {
                $skuData = $skuResult->getData();
                $haveMaster = 0;
                $newSkuData = [];
                $noMasterUnidIds = [];
                foreach ($skuData as $key => &$value) {
                    if ($value['specType'] == StatusCode::$specType['multiple']) {
                        $value['barCode'] = '';
                    }

                    if ($value['isMaster'] == StatusCode::$standard && $haveMaster == 0) {
                        $newSkuData[] = $value;
                        $haveMaster = 1;
                    }
                    if ($value['isMaster'] == StatusCode::$delete && !in_array($value['unitId'], $noMasterUnidIds)) {
                        $newSkuData[] = $value;
                        $noMasterUnidIds[] = $value['unitId'];
                    }
                }
                unset($skuData);
                $skuData = $newSkuData;
            }
            $details['unitData'] = $skuData;
        }


        return $data;
    }


    /**
     * Doc: (des="初始化规格数据")
     * User: XMing
     * Date: 2021/3/4
     * Time: 5:24 下午
     * @param $data
     * @return mixed
     */
    public static function formatInitSpec($data)
    {
        if (empty($data)) {
            return $data;
        }

        $specMultiple = $data['specMultiple'];
        if (empty($specMultiple)){
            return $data;
        }
        //初始化
        $data['minSalePrice'] = 0;//最低价格
        $data['maxSalePrice'] = 0;//最高价
        foreach ($specMultiple as &$spec) {
            $spec['index'] = '';//唯一索引
            $spec['salePrice'] = 0;//销售价格
            $spec['inventory'] = 0;//库存
            $spec['ladderPrice'] = [];//阶梯价格
            $spec['marketPrice'] = 0;//市场价格
            $spec['enabledLadder'] = '';//是否开启阶梯价格
            $spec['setNum'] = 0;//起定数量
            $spec['isActivityPrice'] = StatusCode::$delete;//初始化,是否享受活动价格
            $spec['limitNum'] = 0;//活动商品限购数量
            $spec['originPrice'] = 0;//商品原价
            $spec['costPrice'] = 0;//商品原价
            $spec['salesNum'] = 0;//规格销售量
            $spec['activity'] = [];//活动信息
        }
        $data['specMultiple'] = $specMultiple;
        return $data;
    }

    /**
     * Doc: (des="获取库存")
     * User: XMing
     * Date: 2021/3/4
     * Time: 5:36 下午
     * @param array $data
     * @return ResultWrapper
     * @throws Exception
     */
    private function formatInventorySpec(array $data): ResultWrapper
    {
        if (empty($data)){
            return ResultWrapper::success($data);
        }

        $shopId = getArrayItem($data,'shopId',0);
        $specMultiple = getArrayItem($data,'specMultiple',[]);
        $skuIds = [];
        foreach ($specMultiple as $item){
            if (!in_array($item['id'],$skuIds)){
                $skuIds[] = $item['id'];
            }
        }
        $this->objMInventory = new MInventory($this->enterpriseId, $this->userCenterId);
        $inventoryResult = $this->objMInventory->getInventoryByShopIdAndSkuIds($shopId,$skuIds);
        if (!$inventoryResult->isSuccess()){
            return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
        }
        $inventoryMap = $inventoryResult->getData();
        foreach ($specMultiple as &$item){
            $row = getArrayItem($inventoryMap,$item['id'],[]);
            $item['inventory'] = getArrayItem($row,'num',0);
            $item['otherNum'] = getArrayItem($row,'otherNum',0);
        }
        $data['specMultiple'] = $specMultiple;
        return ResultWrapper::success($data);
    }

    /**
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public function getSkuInventorySpec($data): ResultWrapper
    {
        if (empty($data)) {
            return ResultWrapper::success($data);
        }

        $selectParams = [];
        foreach ($data as $item){
            $selectParams[$item['shopId']][] = $item['basicGoodsId'];
        }

        $this->objMInventory = new MInventory($this->enterpriseId, '');
        $inventoryMap = [];
        foreach ($selectParams as $shopId => $materielIds){
            $inventoryResult = $this->objMInventory->getInventoryByShopIdAndMaterielIds($shopId,$materielIds);
            if (!$inventoryResult->isSuccess()) {
                return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
            }
            $inventoryMap[$shopId] = $inventoryResult->getData();//库存数据
        }

        foreach ($data as &$goods) {
            if (!isset($goods['specType'])){
                //老数据es中可能没有
                $goods['specType'] = StatusCode::$specType['single'];
            }
            $goods['inventorTotal'] = isset($inventoryMap[$goods['shopId']][$goods['basicGoodsId']]['num']) ? $inventoryMap[$goods['shopId']][$goods['basicGoodsId']]['num'] : 0;//当前商品规格总库存
            $goods['inventorTotal'] = floatval($goods['inventorTotal']);
            if (!isset($goods['specMultiple'])) {
                continue;
            }

            $specMultiple = $goods['specMultiple'];
            $skuIds = [];
            foreach ($specMultiple as $spec) {
                $skuIds[] = $spec['skuId'];
            }
            unset($spec);
            $inventoryResult = $this->objMInventory->getInventoryByShopIdAndSkuIds($goods['shopId'],$skuIds);
            if (!$inventoryResult->isSuccess()){
                return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
            }
            $inventoryData = $inventoryResult->getData();
            foreach ($specMultiple as &$spec) {
                $spec['inventory'] = isset($inventoryData[$spec['skuId']]) ? $inventoryData[$spec['skuId']]['num'] : 0;
            }
            $goods['specMultiple'] = $specMultiple;
        }
        return ResultWrapper::success($data);
    }

    /**
     * 单位属性换算
     * @param $spec
     * @param $specType
     * @param $inventoryMapping
     * @param $goods
     * @return mixed
     */
    public function formatConversion($spec, $specType, $inventoryMapping, $goods)
    {
        if (empty($spec)) {
            return $spec;
        }
        //当权商品库存数据
        $thisSpec = isset($inventoryMapping[$goods['basicGoodsId']]['skuData']) ? $inventoryMapping[$goods['basicGoodsId']]['skuData'] : [];
        switch ($specType) {
            case StatusCode::$specType['single']:
                //取出主单位skuId
                $masterSkuId = '';
                foreach ($goods['unitData'] as $value){
                    if ($value['isMaster'] == StatusCode::$standard){
                        $masterSkuId = $value['id'];
                    }
                }
                if ($spec['isNew'] == StatusCode::$standard){
                    //新
                    //主换辅 除
                    //无属性的主单位有采购记录不可编辑，辅助单位可比编辑 4=>有记录 5=>无记录
                    if ($spec['isMaster'] == StatusCode::$standard) {
                        $spec['isEditSpec'] = isset($thisSpec[$masterSkuId]) ? StatusCode::$delete : StatusCode::$standard;
                        $spec['inventory'] = isset($thisSpec[$masterSkuId]) ? $thisSpec[$masterSkuId]['inventoryNum'] : 0;//库存
                    } else {
                        $spec['isEditSpec'] = StatusCode::$delete;
                        $spec['inventory'] = isset($thisSpec[$masterSkuId]) ? bcdiv($thisSpec[$masterSkuId]['inventoryNum'], $spec['conversion'], 8) : 0;//转换库存
                    }
                }else{
                    //旧
                    //主换辅 乘
                    if ($spec['isMaster'] == StatusCode::$standard) {
                        $spec['isEditSpec'] = isset($thisSpec[$masterSkuId]) ? StatusCode::$delete : StatusCode::$standard;
                        $spec['inventory'] = isset($thisSpec[$masterSkuId]) ? $thisSpec[$masterSkuId]['inventoryNum'] : 0;//库存
                    } else {
                        $spec['isEditSpec'] = StatusCode::$delete;
                        $spec['inventory'] = isset($thisSpec[$masterSkuId]) ? bcmul($thisSpec[$masterSkuId]['inventoryNum'], $spec['conversion'], 8) : 0;//转换库存
                    }
                }
                $spec['costPrice'] = isset($thisSpec[$spec['id']]['costPrice']) ? $thisSpec[$spec['id']]['costPrice'] : 0;//成本单价
                break;
            case StatusCode::$specType['multiple']:
                //有属性 同属性主辅换算
                //有属性，主 4=>有记录 5=>无记录
                if ($spec['isNew'] == StatusCode::$standard){
                    //新
                    //主换辅 除
                    if ($spec['isMaster'] == StatusCode::$standard) {
                        $spec['isEditSpec'] = isset($thisSpec[$spec['id']]) ? StatusCode::$delete : StatusCode::$standard;
                        $spec['inventory'] = isset($thisSpec[$spec['id']]) ? $thisSpec[$spec['id']]['inventoryNum'] : 0;//库存
                        $this->allMappingSpec[$spec['specGroupHash']] = $spec;//保存属性组
                    } else {
                        $spec['isEditSpec'] = isset($this->allMappingSpec[$spec['specGroupHash']]) ? $this->allMappingSpec[$spec['specGroupHash']]['isEditSpec'] : StatusCode::$delete;
                        $spec['inventory'] = isset($this->allMappingSpec[$spec['specGroupHash']]) ? bcdiv($this->allMappingSpec[$spec['specGroupHash']]['inventory'], $spec['conversion'], 8) : 0;
                    }
                }else{
                    if ($spec['isMaster'] == StatusCode::$standard) {
                        $spec['isEditSpec'] = isset($thisSpec[$spec['id']]) ? StatusCode::$delete : StatusCode::$standard;
                        $spec['inventory'] = isset($thisSpec[$spec['id']]) ? $thisSpec[$spec['id']]['inventoryNum'] : 0;//库存
                        $this->allMappingSpec[$spec['specGroupHash']] = $spec;//保存属性组
                    } else {
                        $spec['isEditSpec'] = isset($this->allMappingSpec[$spec['specGroupHash']]) ? $this->allMappingSpec[$spec['specGroupHash']]['isEditSpec'] : StatusCode::$delete;
                        $spec['inventory'] = isset($this->allMappingSpec[$spec['specGroupHash']]) ? bcmul($this->allMappingSpec[$spec['specGroupHash']]['inventory'], $spec['conversion'], 8) : 0;
                    }
                }
                $spec['costPrice'] = isset($thisSpec[$spec['id']]['costPrice']) ? $thisSpec[$spec['id']]['costPrice'] : 0;//成本单价
                break;
        }

        $spec['inventory'] = floor($spec['inventory']);
        return $spec;
    }

    /**
     * spec salesNum
     * @param $data
     * @param array $allGoodsIds
     * @return mixed
     * @throws Exception
     */
    public function getSalesNumBySkuSpec($data, $allGoodsIds = [])
    {
        $cartData = [];
        if (!empty($allGoodsIds)) {
            $objMCart = new MCart($this->userCenterId, $this->enterpriseId);
            $cartData = $objMCart->getCartNumByGoodsId($allGoodsIds);
        }


        foreach ($data as &$goods) {
            //[{"skuId":1,"salesNum":10},{"skuId":2,"salesNum":10}]  salesNum
            $salesNumArr = [];
            if (!empty($goods['salesNum'])) {
                $salesNumData = is_string($goods['salesNum']) ? json_decode($goods['salesNum'], true) : $goods['salesNum'];
                $goods['oldSalesNum'] = $salesNumData;//复制旧数据
                $goods['salesNum'] = array_sum(array_column($salesNumData, 'salesNum'));
                if ($salesNumData) {
                    foreach ($salesNumData as $salesNum) {
                        $salesNumArr[$salesNum['skuId']] = $salesNum['salesNum'];
                    }
                }
            } else {
                $goods['salesNum'] = 0;
            }

            if (isset($goods['specMultiple']) && !empty($goods['specMultiple'])) {
                foreach ($goods['specMultiple'] as &$spec) {
                    $spec['salesNum'] = isset($salesNumArr[$spec['id']]) ? $salesNumArr[$spec['id']] : 0;//销量
                    $spec['cartNum'] = isset($cartData[$goods['id']][$spec['id']]) ? $cartData[$goods['id']][$spec['id']] : 0;//购物车数量
                }
            }
        }
        return $data;
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/3/4
     * Time: 7:13 下午
     * @param array $data
     * @return ResultWrapper
     */
    public function getSalesNumDetails_new(array $data): ResultWrapper
    {
        if (empty($data)){
            return ResultWrapper::success([]);
        }


    }

    /**
     * 格式化详情数据，销量
     * @param $data
     * @param array $allGoodsIds
     * @return mixed
     * @throws Exception
     */
    public function getSalesNumDetails($data, $allGoodsIds = [])
    {
        $cartData = [];
        if (!empty($allGoodsIds)) {
            $objMCart = new MCart($this->userCenterId, $this->enterpriseId);
            $cartData = $objMCart->getCartNumByGoodsId($allGoodsIds);
        }

        foreach ($data as &$goods) {
            $salesNumArr = [];
            if (!empty($goods['oldSalesNum'])) {
                $salesNumData = $goods['oldSalesNum'];
                if (is_string($salesNumData)){
                    $salesNumData = json_decode($salesNumData,true);
                }

                unset($goods['oldSalesNum']);
                if (is_array($salesNumData)) {
                    foreach ($salesNumData as $salesNum) {
                        $salesNumArr[$salesNum['skuId']] = $salesNum['salesNum'];
                    }
                }
            }

            if (!empty($goods['salesNum'])){
                $salesNumData = $goods['salesNum'];
                if (is_string($salesNumData)){
                    $salesNumData = json_decode($salesNumData,true);
                }
                if (is_array($salesNumData)){
                    $goods['salesNum'] = array_sum(array_column($salesNumData,'salesNum'));
                }else{
                    $goods['salesNum'] = 0;
                }
                if (is_array($salesNumData)) {
                    foreach ($salesNumData as $salesNum) {
                        $salesNumArr[$salesNum['skuId']] = $salesNum['salesNum'];
                    }
                }
            }


            if (isset($goods['specMultiple']) && !empty($goods['specMultiple'])) {
                foreach ($goods['specMultiple'] as &$spec) {
                    $spec['salesNum'] = isset($salesNumArr[$spec['id']]) ? $salesNumArr[$spec['id']] : 0;//销量
                    $spec['cartNum'] = isset($cartData[$goods['id']][$spec['id']]) ? $cartData[$goods['id']][$spec['id']] : 0;//购物车数量
                }
            }
            if ($this->isFront){
                $goods['salesNum'] = isset($goods['virtualSalesNum']) ? $goods['virtualSalesNum'] : 0;
            }
        }
        return $data;
    }

    /**
     * @param $data
     * @return mixed
     * @throws Exception
     */
    public function getPriceBySkuSpec($data): ResultWrapper
    {
        if (empty($data)) {
            return ResultWrapper::success($data);
        }

        //查询价格参数
        $allGoodsId = [];
        $selectParam['material'] = [];
        foreach ($data as $goods) {
            $allGoodsId[] = $goods['id'];
            $selectParam['material'][$goods['shopId']][] = $goods['id'];
        }
        if (!empty($this->useCustomerId)){
            $selectParam['customerId'] = $this->useCustomerId;//客户有特殊调价
        }

        $priceResult = $this->objMPrice->getPrice($selectParam);
        if (!$priceResult->isSuccess()) {
            return ResultWrapper::fail($priceResult->getData(),$priceResult->getErrorCode());
        }
        $priceResult = $priceResult->getData();

        $goodsPriceMapping = [];
        foreach ($priceResult as $shopPriceArr) {
            foreach ($shopPriceArr as $goodsId => $goodsSkuArr) {
                $goodsPriceMapping[$goodsId] = $goodsSkuArr;
            }
        }

        switch ($this->isFront) {
            case true:  // 前台
                $objMCustomer = new MCustomer($this->enterpriseId, $this->userCenterId);
                $objMActivity = new MActivity($this->userCenterId, $this->enterpriseId);
                if (!empty($this->userCenterId)){
                    $customerResult = $objMCustomer->getCustomerInfoByUserCenterId($this->userCenterId);
                    if (!$customerResult->isSuccess()){
                        return ResultWrapper::fail($customerResult->getData(),$customerResult->getErrorCode());
                    }
                    $customer = $customerResult->getData();
                }
                $activityArr = [];
                //获取促销活动价格
                $dbResult = $objMActivity->getActivity([
                    'goodsId'      => implode(',', $allGoodsId),
                    'customerType' => isset($customer['type']) ? $customer['type'] : 0,
                ]);
                $activityResult = $dbResult->getData();
                unset($dbResult);
                foreach ($activityResult as $activity) {
                    $activityArr[$activity['goodsId'] . $activity['skuId']] = $activity;
                }

                foreach ($data as &$goods) {
                    if (!isset($goodsPriceMapping[$goods['id']])) {
                        //当前商品的价格信息不存在
                        continue;
                    }
                    $goodsPriceInfo = $goodsPriceMapping[$goods['id']];//当前商品价格信息
                    $specMultiple = $goods['specMultiple'];//规格组
                    foreach ($specMultiple as &$spec) {
                        $bool = isset($activityArr[$goods['id'] . $spec['id']]);//是否具有活动价格
                        $spec["marketPrice"] = isset($goodsPriceInfo[$spec['id']]) ? $goodsPriceInfo[$spec['id']]['marketPrice'] : 0;//市场价格
                        $spec["originPrice"] = isset($goodsPriceInfo[$spec['id']]) ? $goodsPriceInfo[$spec['id']]['salePrice'] : 0;//原价
                        // 计算属性最小单位展示价格
                        if(isset($goodsPriceInfo[$spec['id']]['minUnitPriceConvert']) && !empty($goodsPriceInfo[$spec['id']]['minUnitPriceConvert'])){
                            $goodsPriceInfo[$spec['id']]['minUnitPrice'] = bcdiv($goodsPriceInfo[$spec['id']]['salePrice'], $goodsPriceInfo[$spec['id']]['minUnitPriceConvert'], 2);
                        }else{
                            $goodsPriceInfo[$spec['id']]['minUnitPrice'] = '0.00';
                        }

                        if ($bool) {
                            $activityDetails = $activityArr[$goods['id'] . $spec['id']];//活动详情
                            $spec['isActivity'] = StatusCode::$standard;//活动价格
                            //获取用户活动购买数量
                            if (!empty($this->userCenterId)) {
                                $userLimit = (int)$this->objActivityLimitCache->getLimit($activityDetails["activityId"], $goods['id'], $spec['id'], $this->userCenterId);
                                //活动商品用户限购数
                                $goodsLimit = (int)$activityDetails['limitNum'];
                                if ($userLimit < $goodsLimit) {
                                    //此商品相对用户,满足活动价
                                    $spec['isActivityPrice'] = StatusCode::$standard;//满足活动价
                                }
                                $spec['limitNum'] = $goodsLimit;
                            }

                            //具有活动价格
                            $spec["salePrice"] = $activityDetails['price'];//销售价格
                            $spec["minUnitPrice"] = $goodsPriceInfo[$spec['id']]['minUnitPrice'];//属性最小单位展示价
                            $spec["ladderPrice"] = [];//阶梯价格
                            $spec["enabledLadder"] = 0;//是否开启阶梯价阶梯
                            $spec["setNum"] = isset($goodsPriceInfo[$spec['id']]['setNum']) ? $goodsPriceInfo[$spec['id']]['setNum'] : 0;//起定数量
                            $spec["isSale"] = isset($goodsPriceInfo[$spec['id']]['isSale']) ? $goodsPriceInfo[$spec['id']]['isSale'] : 5;//起定数量
                            $spec['minUnitPriceConvert'] = getArrayItem($goodsPriceInfo[$spec['id']], 'minUnitPriceConvert', 0);
                            $spec['activity'] = [
                                'activityId'      => $activityDetails['activityId'],//活动ID
                                'images'          => empty($activityDetails['images']) ? [] : json_decode($activityDetails['images'],true),//活动图片
                                'title'           => $activityDetails['title'],//活动标题
                                'startTime'       => $activityDetails['startTime'],
                                'endTime'         => $activityDetails['endTime'],
                                'activityType'    => $activityDetails['activityType'],//活动类型
                                'activityNum'     => $activityDetails['activityNum'],//活动总数量
                                'limitNum'        => $activityDetails['limitNum'],//用户限购数量
                                'salesPrice'      => $activityDetails['price'],//活动价格
                                'originPrice'     => $spec['originPrice'],//商品原价
                                'goodsActivityId' => $activityDetails['goodsActivityId'],//活动商品表id
                            ];//活动详情
                        } else {
                            if (!isset($goodsPriceInfo[$spec['id']])) {
                                //当前商品sku价格信息不存在
                                continue;
                            }
                            $spec["salePrice"] = $goodsPriceInfo[$spec['id']]['salePrice'];//销售价格
                            $spec["minUnitPrice"] = $goodsPriceInfo[$spec['id']]['minUnitPrice'];// 属性最小单位展示价
                            $spec["memberPrice"] = getArrayItem($goodsPriceInfo[$spec['id']], 'memberPrice', 0); // 会员价格
                            $spec["marketPrice"] = $goodsPriceInfo[$spec['id']]['marketPrice'];//市场价格
                            $spec["ladderPrice"] = $goodsPriceInfo[$spec['id']]['ladderPrice'];//阶梯价格
                            $spec["enabledLadder"] = $goodsPriceInfo[$spec['id']]['enabledLadder'];//是否开启阶梯价阶梯
                            $spec["setNum"] = isset($goodsPriceInfo[$spec['id']]['setNum']) ? $goodsPriceInfo[$spec['id']]['setNum'] : 0;//起定数量
                            $spec["isSale"] = isset($goodsPriceInfo[$spec['id']]['isSale']) ? $goodsPriceInfo[$spec['id']]['isSale'] : 5;//起定数量
                            $spec['minUnitPriceConvert'] = getArrayItem($goodsPriceInfo[$spec['id']], 'minUnitPriceConvert', 0);
                            $spec["isActivity"] = StatusCode::$delete;
                        }
                        $this->commonMapping[$goods['id']][] = $spec["salePrice"];//商品价格集合
                    }
                    $goods['specMultiple'] = $specMultiple;
                }
                break;
            case false;
                //后台
                foreach ($data as &$goods) {
                    if (!isset($goodsPriceMapping[$goods['id']])) {
                        //当前商品的价格信息不存在
                        continue;
                    }
                    $goodsPriceInfo = $goodsPriceMapping[$goods['id']];//当前商品价格信息
                    $specMultiple = $goods['specMultiple'];//规格组
                    foreach ($specMultiple as &$spec) {
                        if (!isset($goodsPriceInfo[$spec['id']])) {
                            //当前商品sku价格信息不存在
                            continue;
                        }
                        $spec["salePrice"] = $goodsPriceInfo[$spec['id']]['salePrice'];//销售价格
                        $spec["memberPrice"] =  getArrayItem($goodsPriceInfo[$spec['id']], 'memberPrice', 0); // 会员价格
                        $spec["marketPrice"] = $goodsPriceInfo[$spec['id']]['marketPrice'];//市场价格
                        $spec["originPrice"] = $goodsPriceInfo[$spec['id']]['salePrice'];//原价
                        $spec["ladderPrice"] = $goodsPriceInfo[$spec['id']]['ladderPrice'];//阶梯价格
                        $spec["enabledLadder"] = $goodsPriceInfo[$spec['id']]['enabledLadder'];//是否开启阶梯价阶梯
                        $spec["setNum"] = isset($goodsPriceInfo[$spec['id']]['setNum']) ? $goodsPriceInfo[$spec['id']]['setNum'] : 0;//起定数量
                        $spec["isSale"] = isset($goodsPriceInfo[$spec['id']]['isSale']) ? $goodsPriceInfo[$spec['id']]['isSale'] : 5;//起定数量
                        $spec['minUnitPriceConvert'] = getArrayItem($goodsPriceInfo[$spec['id']], 'minUnitPriceConvert', 0);
                        $spec["isActivity"] = StatusCode::$delete;

                        $this->commonMapping[$goods['id']][] = $spec["salePrice"];//商品价格集合
                    }
                    $goods['specMultiple'] = $specMultiple;
                }
                break;
        }

        return ResultWrapper::success($data);

    }

    /**
     * @param $data
     * @return mixed
     */
    public function getActivityPrice($data)
    {
        if (empty($data)) {
            return [];
        }

        if (empty($this->customerType)) {
            return [];
        }

        //获取促销活动价格
        $dbResult = $this->objMActivity->getActivity([
            'goodsId'      => implode(',', array_column($data, 'id')),
            'customerType' => $this->customerType,
        ]);
        $activityResult = $dbResult->getData();
        unset($dbResult);
        foreach ($activityResult as $activity) {
            $activityArr[$activity['goodsId'] . $activity['skuId']] = $activity;
        }

    }

    /**
     * 拼接活动
     * @param $goodsData
     * @return mixed
     * @throws Exception
     */
    private function getActivity($goodsData)
    {
        if (empty($goodsData)) return $goodsData;
        $objMActivity = new MActivity($this->userCenterId, $this->enterpriseId);
        $objMCustomer = new MCustomer($this->enterpriseId, $this->userCenterId);
        $customer = $objMCustomer->getCustomerInfoByUserCenterId($this->userCenterId);
        if (!$customer->isSuccess()) {
            return $goodsData;
        }
        $customerType = $customer->getData()['type'];
        $dbResult = $objMActivity->getActivity(['goodsId' => $goodsData['id'], 'customerType' => $customerType]);
        if (!$dbResult->isSuccess()) {
            return $goodsData;
        }
        $allActivity = [];
        foreach ($dbResult->getData() as $activity) {
            $allActivity[$activity['skuId']][] = $activity;
        }

        if (isset($goodsData['skuData'])){
            foreach ($goodsData['skuData'] as &$sku) {
                if (!isset($sku['skuId'])){
                    $sku['activity'] = (object)[];
                    continue;
                }
                $sku['activity'] = isset($allActivity[$sku['skuId']]) ? $allActivity[$sku['skuId']] : (object)[];
            }
        }
        return $goodsData;
    }


    /**
     * 通过区域获取销售店铺
     * @param ?string $areaCode
     * @return ResultWrapper
     */
    public function getShopIdsByArea(?string $areaCode = '')
    {
        $fields = 'id,warehouseId';
        $sql = 'select '.$fields.' from qianniao_shop_1 where 
                enterpriseId = '.$this->enterpriseId;
        if (!empty($areaCode)){
            $sql .= " and (JSON_CONTAINS(salesArea->'$[*]', '\"".$areaCode."\"', '$') OR JSON_CONTAINS(salesArea->'$[*]','\"0-0-0\"','$'))";
        }
        $sql .= ' and warehouseId IS NOT NULL';
        $result = $this->objDGoods->query($sql);
        if ($result === false){
            Logger::logs(E_USER_ERROR,'店铺查询失败',__CLASS__,__LINE__,$this->objDGoods->error());
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }

        //返回数据为空
        if (empty($result)){
            return ResultWrapper::success([]);
        }

        $shopIds = [];
        $shopIdBindWarehouseId = [];
        foreach ($result as $value){
            $shopIds[] = $value['id'];
            $shopIdBindWarehouseId[$value['id']] = $value['warehouseId'];
        }

        $map = [
            'shopIds' => $shopIds,
            'shopIdBindWarehouseId' => $shopIdBindWarehouseId
        ];
        return ResultWrapper::success($map);
    }

    /**
     * 查询商品
     * @param array $condition
     *          shopIds array  店铺ids
     *          keyword string 商品名称
     *          goodsId int    商品id
     *          categoryId int 分类id
     *          orderBy string 排序
     * @param bool $getTotal
     * @return ResultWrapper
     */
    public function getGoodsBySelectParams(array $condition = [],bool $getTotal = false): ResultWrapper
    {
        //数据总条数
        $total = 0;
        $fields = "g.*,(g.realSalesNum) as realSalesNum,
                   b.title,b.description,b.images,b.categoryId,b.brandId,b.specType,b.categoryPath,b.isEq,
                   b.describe,b.categoryPath,b.specGroup,
                   c.title as categoryName,
                   d.title as brandName";

        $sql = 'select '.$fields.' from qianniao_goods_'.$this->enterpriseId.' as g 
                left join qianniao_goods_basic_'.$this->enterpriseId.' as b
                on g.basicGoodsId = b.id 
                left join qianniao_goods_category_'.$this->enterpriseId.' as c 
                on c.id = b.categoryId 
                left join qianniao_goods_brand_'.$this->enterpriseId.' as d 
                on d.id = b.brandId
                where 
                g.deleteStatus = '.StatusCode::$standard;

        if (isset($condition['enableStatus']) && !empty($condition['enableStatus'])){
            $sql .= ' AND g.enableStatus = '.$condition['enableStatus'];
        }

        //品牌Id
        if ( isset($condition['brandId']) && !empty($condition['brandId']) ){
            $sql .= ' AND ';
            if (is_array($condition['brandId'])){
                foreach($condition['brandId'] as $brandIdKey => $brandIdValue){
                    if($brandIdValue == end($condition['brandId'])){//是最后一个
                        $sql .= ' FIND_IN_SET('.$brandIdValue.',b.brandId'.')';
                    }else{
                        $sql .= ' FIND_IN_SET('.$brandIdValue.',b.brandId'.') or ';
                    }
                }
            }else{
                $sql .= ' b.brandId = '.$condition['brandId'];
            }
        }

        //商品服务
        if (isset($condition['support']) && !empty($condition['support'])){
            $sql .= ' AND ';
            if (is_array($condition['support'])) {
                foreach ($condition['support'] as $supportKey => $supportValue) {
                    if ($supportValue == end($condition['support'])) {//是最后一个
                        $sql .= ' FIND_IN_SET(' . $supportValue . ',g.support' . ')';
                    } else {
                        $sql .= ' FIND_IN_SET(' . $supportValue . ',g.support' . ') or ';
                    }
                }
            }else{
                $sql .= ' FIND_IN_SET('.$condition['support'].',g.support'.')';
            }

        }

        //商品分组
        if (isset($condition['goodsGroups']) && !empty($condition['goodsGroups'])){
//            $sql .= ' AND ';
//            foreach($condition['goodsGroups'] as $supportKey => $supportValue){
//                if($supportValue == end($condition['goodsGroups'])){//是最后一个
//                    $sql .= ' FIND_IN_SET('.$supportValue.',g.goodsGroups'.')';
//                }else{
//                    $sql .= ' FIND_IN_SET('.$supportValue.',g.goodsGroups'.') or ';
//                }
//            }
            $sql .= ' AND FIND_IN_SET('.$condition['goodsGroups'].',g.goodsGroups'.')';
        }

        //商品id
        if (isset($condition['goodsId']) && !empty($condition['goodsId'])){
            $sql .= ' and g.id = '.$condition['goodsId'];
        }

        //过滤商品id
        if (isset($condition['notGoodsIds']) && !empty($condition['notGoodsIds'])){
            $notGoodsIdsStr = implode(',',$condition['notGoodsIds']);
            $sql .= ' and g.id not in('.$notGoodsIdsStr.') ';
        }

        //查询的商品id
        if (isset($condition['goodsIds']) && !empty($condition['goodsIds'])){
            $goodsIdsStr = implode(',',$condition['goodsIds']);
            $sql .= ' and g.id in('.$goodsIdsStr.') ';
        }
        
        if( isset($condition['merchantId']) && !empty($condition['merchantId'])){
            $sql .= ' AND g.merchantId = '.$condition['merchantId'];
        } else {
            if (isset($condition['ifMerchant']) ){
                if($condition['ifMerchant'] == StatusCode::$delete){
                    $sql .= ' AND g.merchantId = 0';
                } else {
                    $sql .= ' AND g.merchantId <> 0';
                }
            }
        }
        //店铺ids array
        if(isset($condition['shopId']) && !empty($condition['shopId'])){
            if (is_array($condition['shopId'])){
                $str = implode(',',$condition['shopId']);
                $sql .= ' and g.shopId in('.$str.')';
            }else{
                $sql .= ' and g.shopId = '.(int)$condition['shopId'];
            }
        }else{
            if (isset($condition['shopIds']) && !empty($condition['shopIds'])){
                $str = implode(',',$condition['shopIds']);
                $sql .= ' and g.shopId in('.$str.')';
            }
        }

        //商品关键字
        if (isset($condition['keyword']) && !empty($condition['keyword'])){
            $keywordId = 0;
            preg_match_all( '/\d+/' , $condition['keyword'] , $arr);
            if (isset($arr) && is_array($arr)){
                $arr = array_shift($arr);
                $keywordId = isset($arr[0]) ? (int)floatval($arr[0]) : 0;
            }
            $sql .= ' AND ( b.title like "%'.$condition['keyword'].'%" ';
            if (!empty($keywordId)){
                $sql .= ' OR b.id = '.$keywordId;
            }
            $sql .= ' ) ';
        }

        //分类路径
        if (isset($condition['categoryPath']) && !empty($condition['categoryPath'])){
            if (is_string($condition['categoryPath']) || is_int($condition['categoryPath'])){
                $condition['categoryPath'] = explode(',',$condition['categoryPath']);
            }
            $endPathId = array_pop($condition['categoryPath']);
            if (!empty($endPathId)){
                $sql .= ' and (find_in_set('.$endPathId.',b.categoryPath) or find_in_set('.$endPathId.',b.assistCategoryId)) ';
            }
        }

        //分类id
        if (isset($condition['categoryId']) && !empty($condition['categoryId'])){
            $sql .= ' and (find_in_set('.$condition['categoryId'].',b.categoryPath) or find_in_set('.$condition['categoryId'].',b.assistCategoryId)) ';
        }

        if (isset($condition['inStock'])) {
            $goodsBasicIdResult = self::getInOrOutOfStockGoodsBasicId($condition['inStock']);
            if (!$goodsBasicIdResult->isSuccess()) {
                return ResultWrapper::fail($goodsBasicIdResult->getData(), $goodsBasicIdResult->getErrorCode());
            }
            $goodsBasicIds = $goodsBasicIdResult->getData();
            $where = '';
            if (!empty($goodsBasicIds)) {
                $where .= " AND (";
                foreach ($goodsBasicIds as $key => $goodsBasicId) {
                    $cond = $key ? " OR " : "";
                    $where .= $cond . '(g.basicGoodsId = ' . $goodsBasicId['basicGoodsId'] . ' and g.shopId=' . $goodsBasicId['shopId'] . ')';
                }
                $where .= ") ";
            }
            $sql .= $where;
        }

        //查询数据总条数
        if ($getTotal === true){
            $total = count((array)$this->objDGoods->query($sql));
        }

        //排序
//        if (isset($condition['orderBy']) && !empty($condition['orderBy'])){
//            $sql .= ' order by '.$condition['orderBy'];
//        }else{
//            $sql .= ' order by g.topTime DESC,g.createTime DESC ';
//        }
        //销售排序
        if ( isset($condition['sort']) && !empty($condition['sort']) ){

            if ($condition['sort'] == 1){//倒序
                $sql .= ' order by g.topTime DESC,realSalesNum DESC,g.createTime DESC';
            }else{
                $sql .= ' order by g.topTime DESC,realSalesNum ASC,g.createTime DESC';
            }
        }else{
            $sql .= ' order by g.topTime DESC,g.createTime DESC';
        }

        


//        if ( isset($condition['priceSort']) && !empty($condition['priceSort']) ){
//            $sql .= ',g. DESC';
//        }

        //分页
        if (isset($condition['offset']) && isset($condition['limit']) && !empty($condition['limit'])){
            $sql .= ' limit '.$condition['offset'].','.$condition['limit'];
        }

        $dbResult = $this->objDGoods->query($sql);
        if ($dbResult === false){
            Logger::logs(E_USER_ERROR,'查询商品失败',__CLASS__,__LINE__,$this->objDGoods->error());
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        //销量放进去
//        V($dbResult);
//        $salesNumArray = (array)json_decode(getArrayItem($goods,'salesNum',''),true);
//        unset($goods['salesNum']);
//        $goods['salesNum'] = array_sum(array_column($salesNumArray,'salesNum'));

        $map = [
            'total' => $total,
            'data'  => $dbResult
        ];
        return ResultWrapper::success($map);
    }

    /**
     * 商品数据/最高最低价格
     * @param array $data
     * @param array $shopIdBindWarehouseId
     * @return ResultWrapper
     * @throws Exception
     */
    private function formatGoodsData(array $data,array $shopIdBindWarehouseId)
    {
        if(empty($data)){
            return ResultWrapper::success($data);
        }

        // 最高最低价格
        $priceResult = $this->objMPrice->getPolePrice(array_column($data,'id'),$this->useCustomerId);
        if (!$priceResult->isSuccess()){
            return ResultWrapper::fail($priceResult->getData(),$priceResult->getErrorCode());
        }
        $allRangePriceData = $priceResult->getData();

        //unitData
        $condition = ['basicGoodsIds'=> array_column($data,'basicGoodsId')];
        $unitDataResult = self::getUnitDataBySelectParams($condition);
        if (!$unitDataResult->isSuccess()){
            return ResultWrapper::fail($unitDataResult->getData(),$unitDataResult->getErrorCode());
        }
        $allUnitData = $unitDataResult->getData();

        foreach ($data as $key => &$value){
            $value['unitData'] = isset($allUnitData[$value['basicGoodsId']]) ? $allUnitData[$value['basicGoodsId']] : [];
            $value['images'] = empty(json_decode($value['images'], true)) ? [] : json_decode($value['images'], true);
            $value['specGroup'] = empty(json_decode($value['specGroup'], true)) ? [] : json_decode($value['specGroup'], true);
            $value['title'] = htmlspecialchars_decode($value['title'], ENT_QUOTES);
            $description = htmlspecialchars_decode($value['description'], ENT_QUOTES);
            $description = str_replace('?imageView2/2/w/750/h/750','',$description);
            $description = str_replace('?imageView2/2/w/750','',$description);
            $value['content'] = $description;
            $value['description'] = $description;
            $value['warehouseId'] = isset($shopIdBindWarehouseId[$value['shopId']]) ? $shopIdBindWarehouseId[$value['shopId']] : null;
            $value['minSalePrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['minSalePrice'] : 0;
            $value['maxSalePrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['maxSalePrice'] : 0;
            $value['minMarketPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['minMarketPrice'] : 0;
            $value['maxMarketPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['maxMarketPrice'] : 0;
            $value['minMemberPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['minMemberPrice'] : 0;
            $value['maxMemberPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['maxMemberPrice'] : 0;
            $value['marketPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['minMarketPrice'] : 0;
            $value['minMinUnitPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['minMinUnitPrice'] : 0;
            $value['maxMinUnitPrice'] = isset($allRangePriceData[$value['id']]) ? $allRangePriceData[$value['id']]['maxMinUnitPrice'] : 0;
        }

        $inventoryResult = self::getSkuInventorySpec($data);
        if (!$inventoryResult->isSuccess()){
            return ResultWrapper::fail($inventoryResult->getData(),$inventoryResult->getErrorCode());
        }
        $data = $inventoryResult->getData();
        return ResultWrapper::success($data);
    }

    /**
     * Doc: (des="格式化json数据以及销量")
     * User: XMing
     * Date: 2020/7/14
     * Time: 11:08 上午
     * @param array $data
     * @return array
     */
    public static function formatJsonGoods(array $data)
    {
        if (empty($data)){
            return $data;
        }
        foreach ($data as &$item){
            if (!isset($item['virtualSalesNum'])){
                $item['salesNum'] = 0;
                continue;
            }
            $item['salesNum'] = (int) $item['virtualSalesNum'];
        }
        return $data;
    }

    /**
     * @param array $condition
     * @return ResultWrapper
     */
    private function getUnitDataBySelectParams(array $condition = [])
    {
        $fields = 'id,unitId,unitName,conversion,goodsId,isMaster,barCode,specType';
        $sql = 'SELECT '.$fields.' FROM qianniao_sku_' . $this->enterpriseId . ' 
                WHERE deleteStatus=' . StatusCode::$standard;
        if (isset($condition['basicGoodsIds']) && !empty($condition['basicGoodsIds'])){
            $str = implode(',',$condition['basicGoodsIds']);
            $sql .= ' and goodsId in('.$str.')';
        }

        $dbResult = $this->objDGoods->query($sql);
        if ($dbResult === false){
            Logger::logs(E_USER_ERROR,'获取单位出错',__CLASS__,__LINE__,$this->objDGoods->error());
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $haveMaster = [];
        $noMasterUnitIds = [];
        foreach ($dbResult as $key => $item){
            $haveMaster[$item['goodsId']] = 0;
            $noMasterUnitIds[$item['goodsId']] = [];
        }

        $newSkuData = [];
        foreach ($dbResult as $key => &$value) {
            if ($value['specType'] == StatusCode::$specType['multiple']) {
                $value['barCode'] = '';
            }

            if ($value['isMaster'] == StatusCode::$standard  && $haveMaster[$value['goodsId']] == 0) {
                $newSkuData[$value['goodsId']][] = $value;
                $haveMaster[$value['goodsId']] = 1;
            }
            if ($value['isMaster'] == StatusCode::$delete && !in_array($value['unitId'], $noMasterUnitIds[$value['goodsId']])) {
                $newSkuData[$value['goodsId']][] = $value;
                $noMasterUnitIds[$value['goodsId']][] = $value['unitId'];
            }
        }

        return ResultWrapper::success($newSkuData);
    }



    /**
     * 前台获取商品详情
     * @param $goodsId
     * @param $areaCode
     * @return ResultWrapper
     * @throws Exception
     */
    public function getApiGoodsInfo($goodsId, $areaCode = ''): ResultWrapper
    {
        $shopResult = self::getShopIdsByArea($areaCode);
        if (!$shopResult->isSuccess()){
            return ResultWrapper::fail($shopResult->getData(),ErrorCode::$dberror);
        }
        $shopData = $shopResult->getData();//销售区域店铺数据
        if (empty($shopData)){
            return ResultWrapper::fail('商品不再此区域销售', ErrorCode::$notAllowAccess);
        }

        // 查询商品数据
        $condition = [
            'goodsId' => $goodsId,
            'shopIds' => $shopData['shopIds']
        ];
        $goodsResult = self::getGoodsBySelectParams($condition,false);
        if (!$goodsResult->isSuccess()){
            return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
        }
        $goodsData = $goodsResult->getData()['data'];
        if (empty($goodsData)){
            return ResultWrapper::fail('商品不在此区域销售',ErrorCode::$paramError);
        }

        //获取客户id
        !empty($this->userCenterId) && $this->useCustomerId = $this->objMCustomer->getCustomerIdByUserCenterId($this->userCenterId);

        // 格式化商品数据
        $formatGoodsRes = self::formatGoodsData($goodsData,$shopData['shopIdBindWarehouseId']);
        if (!$formatGoodsRes->isSuccess()){
            return ResultWrapper::fail($formatGoodsRes->getData(),$formatGoodsRes->getErrorCode());
        }
        $goodsData = $formatGoodsRes->getData();
        $goodsData = array_shift($goodsData);

        $goodsDataResult = self::formatDetails($goodsData);
        if (!$goodsDataResult->isSuccess()){
            return ResultWrapper::fail($goodsDataResult->getData(),$goodsDataResult->getErrorCode());
        }
        $goodsData = $goodsDataResult->getData();
        $goodsDataResult = self::formatGoodsExpress($goodsData);
        if (!$goodsDataResult->isSuccess()){
            return ResultWrapper::fail($goodsDataResult->getData(),$goodsDataResult->getErrorCode());
        }
        $goodsData = $goodsDataResult->getData();
        $goodsData = self::ruleSalePrice($goodsData);//按固定规则获取价格
        $goodsData = self::getActivity($goodsData);
        $goodsData['isCollect'] = $this->objMGoodsCollect->hasCollect($goodsData['id']);
        
        // 写入客户浏览商品记录数
        $objMCustomerVisitsLog = new MCustomerVisitsLog($this->enterpriseId, $this->userCenterId);
        $customerVisitsData = [
            'usercenterid' => $this->userCenterId,
            'customerid'   => $this->useCustomerId,
            'shopid'       => $goodsData['shopId'],
            'goodsid'      => $goodsData['basicGoodsId'],
            'createTime'   => time(),
        ];
        $objMCustomerVisitsLog->addCustomerVisitsLog($customerVisitsData);
        // 展示商品服务信息
        $objMGoodsSupport = new MGoodsSupport($this->enterpriseId, $this->userCenterId);
        $supportId = $goodsData['support'];
        $supportresult =  $objMGoodsSupport->getGoodsSupport($supportId);
        if(!$supportresult->isSuccess()){
            return ResultWrapper::fail($supportresult->getData(),$supportresult->getErrorCode());
        }
        $goodsData['support'] = $supportresult->getData();
        
        return ResultWrapper::success($goodsData);
    }

    /**
     * Doc: (des="根据规则处理商品详情默认显示的价格")
     * User: XMing
     * Date: 2020/8/14
     * Time: 5:32 下午
     * @param array $data
     * @return array
     */
    private function ruleSalePrice(array $data)
    {
        if (empty($data)){
            return $data;
        }
        if (!isset($data['specMultiple'])){
            return $data;
        }
        $specMultiple = $data['specMultiple'];
        foreach ($specMultiple as &$value){
            if (isset($value['salePrice']) && empty($value['salePrice'])){
                $value['salePrice'] = '0.00';
            }
        }
        $data['specMultiple'] = $specMultiple;
        unset($value);

        $salePrice = 0;
        foreach ($specMultiple as $value){
            if (isset($value['isDefault']) && $value['isDefault'] == StatusCode::$standard){
                $salePrice = $value['salePrice'];//默认规格的价格
                break;
            }
        }
        if ($salePrice != 0){
            //1。如果默认规格价格不为0，用默认价格
            $data['salePrice'] = $salePrice;
            return $data;
        }
        //2。默认价格没有，用最低价格
        $salePrice = $data['minSalePrice'];//最低价格
        if($salePrice != 0){
            $data['salePrice'] = $salePrice;
            return $data;
        }

        //3.取谷歌中有价格的
        foreach ($specMultiple as $value){
            if (isset($value['salePrice']) && $value['salePrice'] != 0){
                $salePrice = $value['salePrice'];
                break;
            }
        }
        $data['salePrice'] = $salePrice;
        return $data;
    }

    /**
     * 根据商品ids数组获取商品names
     * @param $ids
     * @return array|ResultWrapper
     * @throws Exception
     */
    public function getNameByGoodsIds($ids)
    {
        if (empty($ids)){
            return ResultWrapper::success([]);
        }
        $objDGoodsBasic = new DGoodsBasic();
        $objDGoodsBasic->setTable($objDGoodsBasic->get_Table() . '_' . $this->enterpriseId);
        $GoodsBasic = $objDGoodsBasic->select($ids, 'title,extends,specType,isEq,categoryId,categoryPath,brandId,id,images,`describe`');
        if ($GoodsBasic === false) {
            return ResultWrapper::fail($objDGoodsBasic->error(), ErrorCode::$dberror);
        }
        $returnData = [];
        foreach ($GoodsBasic as $value) {
            $extJson = empty($value['extends']) ? [] : json_decode($value['extends'],true);
            $returnData[$value['id']]['storageCode'] = isset($extJson['storage']) ? $extJson['storage'] : '';
            $returnData[$value['id']]['title'] = $value['title'];
            $returnData[$value['id']]['describe'] = htmlspecialchars_decode($value['describe']);
            $returnData[$value['id']]['images'] = json_decode($value['images']);
            $returnData[$value['id']]['categoryId'] = $value['categoryId'];
            $returnData[$value['id']]['brandId'] = $value['brandId'];
            $returnData[$value['id']]['categoryPath'] = $value['categoryPath'];
            $returnData[$value['id']]['specType'] = $value['specType'];
            $returnData[$value['id']]['isEq'] = $value['isEq'];
        }
        return ResultWrapper::success($returnData);
    }

    /**
     * 商品上下架
     * @param array $params
     * @return ResultWrapper
     * @throws Exception
     * @throws Exception
     */
    public function updateEnableStatus($params)
    {
        if (!empty($params['deleteStatus'])){
            $is_status['deleteStatus'] = $params['deleteStatus'];
        }else{
            $is_status['enableStatus'] = $params['enableStatus'];
        }
        $dbResult = $this->objDGoods->update($is_status, $params['id']);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        } else {
            /*if (is_array($params['id'])) {
                foreach ($params['id'] as $id) {
                    $_id = self::createEsDocumentId($id);
                    $this->objDGoods->esupdateTypeFieldVaule(['enableStatus' => $params['enableStatus']], $_id);
                }
            } else {
                $_id = self::createEsDocumentId($params['id']);
                $this->objDGoods->esupdateTypeFieldVaule(['enableStatus' => $params['enableStatus']], $_id);
            }*/

            return ResultWrapper::success($dbResult);
        }
    }

    /**
     * 商品库存为0自动下架
     * @param $updateData
     * @param $where
     * @return ResultWrapper
     */
    public function updateGoodsData($updateData, $where)
    {
        $goods = $this->objDGoods->get($where);
        if ($goods === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }

        if (empty($goods)) {
            return ResultWrapper::fail('该商品不存在', ErrorCode::$dberror);
        }

        $dbResult = $this->objDGoods->update($updateData, $where);
        if ($dbResult === false) {
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        /*
        $_id = self::createEsDocumentId($goods['id']);
        $this->objDGoods->esupdateTypeFieldVaule($updateData, $_id);*/
        return ResultWrapper::success($dbResult);

    }

    /**
     * @param string $barcode
     * @return ResultWrapper
     * @throws Exception
     */
    public function getGoodsByBarCode(string $barcode)
    {
        $sql = "SELECT g.id as goodsId,g.enableStatus,g.deleteStatus,
                s.id as skuId,s.unitName,s.specData,s.unitId
                FROM qianniao_goods_".$this->enterpriseId." as g 
                LEFT JOIN qianniao_sku_".$this->enterpriseId." as s ON s.goodsId=g.basicGoodsId 
                WHERE s.barCode='".$barcode."' AND g.deleteStatus = ".StatusCode::$standard." AND s.deleteStatus = ".StatusCode::$standard;
        $dbResult = $this->objDGoodsBasic->query($sql);
        if ($dbResult === false){
            return ResultWrapper::fail($this->objDGoodsBasic->error(),ErrorCode::$dberror);
        }

        $dbResult = (array) $dbResult;
        if (empty($dbResult) || empty($dbResult[0]['goodsId'])){
            return ResultWrapper::fail("没有找到对应商品",ErrorCode::$paramError);
        }

        //搜索出商品可能不唯一
        $goods = array_shift($dbResult);
        if ($goods['enableStatus'] == StatusCode::$delete){
            return ResultWrapper::fail('商品已下架',ErrorCode::$paramError);
        }

        $goods = self::createIndex($goods);
        $goodsDetail = self::formatGoodsDetail($goods);
        if (!$goodsDetail->isSuccess()){
            return ResultWrapper::fail($goodsDetail->getData(),$goodsDetail->getErrorCode());
        }
        $goods['detail'] = $goodsDetail->getData();
        return ResultWrapper::success($goods);
    }

    /**
     * @param array $goods
     * @throws Exception
     */
    public function formatGoodsDetail(array $goods)
    {
        $goodsDetail = self::getGoodsInfo($goods['goodsId']);
        if (!$goodsDetail->isSuccess()){
            return ResultWrapper::fail($goodsDetail->getData(),$goodsDetail->getErrorCode());
        }
        $goodsDetail = $goodsDetail->getData();
        return ResultWrapper::success($goodsDetail);
    }

    /**
     * @param array $goods
     * @return array
     */
    public static function createIndex(array $goods)
    {

        $map = [
            'goodsId' => '',
            'index'   => '',
            'skuId'   => '',
        ];
        if (empty($goods)){
            return $map;
        }

        $specData = empty($goods['specData']) ? [] : json_decode($goods['specData'],true);
        $map['goodsId'] = $goods['goodsId'];
        $map['skuId'] = $goods['skuId'];
        $index = $goods['goodsId'].':'.$goods['unitId'];
        if (!empty($specData)){
            foreach ($specData as $row) {
                $index .= empty($index) ? $row['specValueId'] : ':' . $row['specValueId'];
            }
        }
        $map['index'] = $index;
        return $map;
    }

    /**
     * @param array $selectParams
     * @return ResultWrapper
     * @throws Exception
     */
    public function getAllGoodsBySku(array $selectParams)
    {
        $customerResult = self::getCustomerIdAndCustomerTypeByUserCenterId($selectParams);
        if (!$customerResult->isSuccess()){
            return ResultWrapper::fail($customerResult->getData(),$customerResult->getErrorCode());
        }

        $fields = 's.id as skuId,s.conversion,s.unitName,s.isMaster,s.unitId,s.specData as specGroup,s.isNew,s.barCode,
                    b.title,b.images,b.id as basicGoodsId,b.specType,b.brandId,b.categoryPath,b.extends,b.supplierId,b.isEq,g.isDistribution,
                    c.title as categoryName,
                    g.shopId,g.id as id,
                    p.name as shopName,p.warehouseId,
                    d.title AS brandName,b.merchantId';

        $sql = 'SELECT '.$fields.' FROM qianniao_sku_'.$this->enterpriseId.' as s 
                LEFT JOIN qianniao_goods_basic_'.$this->enterpriseId.' as b ON s.goodsId=b.id 
                LEFT JOIN qianniao_goods_'.$this->enterpriseId.' as g ON b.id=g.basicGoodsId 
                LEFT JOIN qianniao_goods_category_'.$this->enterpriseId.' as c ON c.id=b.categoryId 
                LEFT JOIN qianniao_shop_1 as p ON p.id = g.shopId 
                LEFT JOIN qianniao_goods_brand_'.$this->enterpriseId.' AS d ON b.brandId = d.id 
                WHERE s.deleteStatus= '.StatusCode::$standard.' 
                AND g.deleteStatus = '.StatusCode::$standard.' 
                AND g.enableStatus= '.StatusCode::$standard.'';

        //店铺id
        if (isset($selectParams['shopId']) && !empty($selectParams['shopId'])){
            $shopStr = is_array($selectParams['shopId']) ? rtrim(implode(',',$selectParams['shopId']),',') : $selectParams['shopId'];
            $sql .= ' AND g.shopId In ('.$shopStr.')';
        }

        if (isset($selectParams['isRevealSku']) && !empty($selectParams['isRevealSku']) && $selectParams['isRevealSku'] == StatusCode::$standard){
            $sql .= ' AND s.isMaster = '.StatusCode::$standard;
        }

        //筛选分类
        if (isset($selectParams['categoryId']) && !empty($selectParams['categoryId'])){
            $sql .= ' and find_in_set('.$selectParams['categoryId'].',b.categoryPath) ';
        }

        //商品名称，字母
        if (isset($selectParams['keyword']) && !empty($selectParams['keyword'])){
            $keyword = '%'.$selectParams['keyword'].'%';
            $sql .= ' AND (b.title LIKE "'.$keyword.'" OR b.condition LIKE "'.$keyword.'" OR s.barCode LIKE "'.$keyword.'")';
        }

        $total = count((array)$this->objDGoodsBasic->query($sql));

        $sql .= ' ORDER BY g.createTime DESC LIMIT '.$selectParams['offset'].','.$selectParams['limit'].'';

        $dbResult = $this->objDGoodsBasic->query($sql);
        if ($dbResult === false){
            return ResultWrapper::fail($this->objDGoodsBasic->error(),ErrorCode::$dberror);
        }
        //抄码商品支持主单位购买
        /*foreach ($dbResult as $key => $item){
            if ($item['isEq'] == StatusCode::$standard && $item['isMaster'] == StatusCode::$standard){
                unset($dbResult[$key]);
            }
        }*/
        $dbResult = array_values($dbResult);
        $dbResult = self::formatList($dbResult);

        if (!$dbResult->isSuccess()){
            return ResultWrapper::fail($dbResult->getData(),$dbResult->getErrorCode());
        }

        $return = [
            'data'  => $dbResult->getData(),
            'total' => $total,
        ];
        return ResultWrapper::success($return);
    }

    /**
     * 获取所有sku
     */
    public function getAllSku($params)
    {
        $where['goodsId'] = $params['id'];
        $dbResult = $this->objDSku->select($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
        }
        $return = [];
        if(!empty($dbResult)){
            foreach($dbResult as $value){
                $value['specData'] = json_decode($value['specData'], true);
                $return[$value['goodsId']][] = $value;
            }
        }
        return ResultWrapper::success($return);
    }

    /**
     * @param $data
     * @return ResultWrapper
     * @throws Exception
     */
    public function formatList(array $data): ResultWrapper
    {
        if (empty($data)){
            return ResultWrapper::success($data);
        }

        //获取库存
        $inventorySelectParams = [];
        $selectParam['material'] = [];
        $supplierIds = [];
        foreach ($data as $goods){
            $selectParam['material'][$goods['shopId']][] = $goods['id'];
            !empty($goods['supplierId']) && $supplierIds[] = $goods['supplierId'];
            $inventorySelectParams[$goods['shopId']][] = $goods['skuId'];
        }
        if (!empty($this->useCustomerId)){
            $selectParam['customerId'] = $this->useCustomerId;//客户有特殊调价
        }

        $this->objMInventory = new MInventory($this->enterpriseId, $this->userCenterId);
        $inventoryMapping = [];
        foreach ($inventorySelectParams as $shopId => $skuIds){
            $inventorySkuResult = $this->objMInventory->getInventoryByShopIdAndSkuIds($shopId,$skuIds);
            if (!$inventorySkuResult->isSuccess()){
                return ResultWrapper::fail($inventorySkuResult->getData(),$inventorySkuResult->getErrorCode());
            }
            $inventoryMapping[$shopId] = $inventorySkuResult->getData();
        }

        $priceResult = $this->objMPrice->getPrice($selectParam);
        if (!$priceResult->isSuccess()) {
            return ResultWrapper::fail($priceResult->getData(),$priceResult->getErrorCode());
        }
        $goodsPriceMapping = [];
        $priceResult = $priceResult->getData();
        foreach ($priceResult as $shopPriceArr) {
            foreach ($shopPriceArr as $goodsId => $goodsSkuArr) {
                $goodsPriceMapping[$goodsId] = $goodsSkuArr;
            }
        }

        $objMSupplier = new MSupplier($this->userCenterId,$this->enterpriseId);
        $supplierResult = $objMSupplier->getSupplierNameByIds($supplierIds);
        if (!$supplierResult->isSuccess()){
            return ResultWrapper::fail($supplierResult->getData(),$supplierResult->getErrorCode());
        }
        $supplierMap = MSupplier::supplierMap($supplierResult->getData());

        foreach ($data as &$value){
            $extends = (isset($value['extends']) && !empty($value['extends'])) ? json_decode($value['extends'],true) : [];
            unset($value['extends']);
            $value['brandName'] = is_null($value['brandName']) ? '' : $value['brandName'];
            $value['storageCode'] = isset($extends['storage']) ? $extends['storage'] : '';
            $value['specGroup'] = empty($value['specGroup']) ? [] : json_decode($value['specGroup'],true);
            $value['images'] = empty($value['images']) ? [] : json_decode($value['images'],true);
            $value['conversion'] = empty($value['conversion']) ? 0 : $value['conversion'];
            $value['code'] = createCode(StatusCode::$code['goodsBasic']['prefix'], $value['basicGoodsId'], StatusCode::$code['goodsBasic']['length']);
            $value['salePrice'] = isset($goodsPriceMapping[$value['id']][$value['skuId']]['salePrice']) ? $goodsPriceMapping[$value['id']][$value['skuId']]['salePrice'] : 0;
            $value['originPrice'] = $value['salePrice'];
            $value['enabledLadder'] = isset($goodsPriceMapping[$value['id']][$value['skuId']]['enabledLadder']) ? $goodsPriceMapping[$value['id']][$value['skuId']]['enabledLadder'] : 0;
            $value['ladderPrice'] = isset($goodsPriceMapping[$value['id']][$value['skuId']]['ladderPrice']) ? $goodsPriceMapping[$value['id']][$value['skuId']]['ladderPrice'] : [];
            $value['supplierName'] = isset($supplierMap[$value['supplierId']]) ? $supplierMap[$value['supplierId']]['title'] : '';
            $value['enabledLadder'] = isset($goodsPriceMapping[$value['id']][$value['skuId']]['enabledLadder']) ? $goodsPriceMapping[$value['id']][$value['skuId']]['enabledLadder'] : 0;
            if (!isset($inventoryMapping[$value['shopId']])){
                return ResultWrapper::fail('店铺库存查询异常',ErrorCode::$paramError);
            }
            $row = $inventoryMapping[$value['shopId']];
            $value['inventory'] = isset($row[$value['skuId']]) ? $row[$value['skuId']]['num'] : 0;
            $value['inventory'] = floor($value['inventory']);
        }
        return ResultWrapper::success($data);
    }

    /**
     * Doc: (des="设置商品置顶/取消商品置顶")
     * User: XMing
     * Date: 2020/8/28
     * Time: 11:07 上午
     * @param int $goodsId
     * @return ResultWrapper
     */
    public function setTop(int $goodsId)
    {
        $goodsInfo = $this->objDGoods->get(['id' => $goodsId],'*');
        if ($goodsInfo === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        if (empty($goodsInfo)){
            return ResultWrapper::fail('未查询到指定商品',ErrorCode::$paramError);
        }
        if (empty($goodsInfo['topTime'])){
            $topTime = time();
        }else{
            $topTime = 0;
        }
        $updateTime = time();
        $updateResult = $this->objDGoods->update(['topTime' => $topTime,'updateTime' => $updateTime],['id' => $goodsId]);
        if ($updateResult === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        /*
        $_id = self::createEsDocumentId($goodsId);
        $this->objDGoods->esupdateTypeFieldVaule(['topTime' => $topTime,'updateTime' => $updateTime], $_id);*/
        return ResultWrapper::success('操作成功');
    }
    
    
    /**
     * Doc: (des="修改排序字段")
     */
    public function setSort($params)
    {
        
        $goodsInfo = $this->objDGoods->get(['id' => $params['id']]);
        if ($goodsInfo === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        if (empty($goodsInfo)){
            return ResultWrapper::fail('未查询到指定商品',ErrorCode::$paramError);
        }
        $updateTime = time();
        $updateResult = $this->objDGoods->update(['sort' => $params['sort'],'updateTime' => $updateTime],['id' => $params['id']]);
        if ($updateResult === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        return ResultWrapper::success('操作成功');
    }
    
    /**
     * Doc: (des="批量设置虚拟销量")
     * User: XMing
     * Date: 2020/9/3
     * Time: 9:35 上午
     * @param array $data
     * @return ResultWrapper
     * @throws Exception
     */
    public function setSalesNumBatch(array $data)
    {
        $beginTransactionStatus = $this->objDGoods->beginTransaction();

        foreach ($data['ids'] as $id){
            $tmpSalesNum = 0;
            $rand = random_int($data['minVal'],$data['maxVal']);
            $updateResult = $this->objDGoods->update(['virtualSalesNum' => $rand],['id' => $id]);
            if ($updateResult === false){
                return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
            }
            // 同步更新真实销量
            $dbResult = $this->objDGoods->get($id);
            if ($dbResult === false){
                return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
            }
            if(empty($dbResult)){
                return ResultWrapper::fail('当前操作的商品不存在。id='.$id,ErrorCode::$notAllowAccess);
            }
            if(isset($dbResult['salesNum']) && !empty($dbResult['salesNum']) ){
                $salesNumInfo = json_decode($dbResult['salesNum'],true);
            }
            foreach ($salesNumInfo as $key => $value){
                $tmpSalesNum = bcadd($value['salesNum'],$tmpSalesNum);
            }
            //更新真实销量
            $update = $this->objDGoods->update(['realSalesNum' => $tmpSalesNum],['id' => $id]);
            if ($update === false){
                return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
            }
            //
            /*
            $_id = self::createEsDocumentId($id);
            $this->objDGoods->esupdateTypeFieldVaule(['virtualSalesNum' => $rand], $_id);*/
        }

        if($beginTransactionStatus){
            $this->objDGoods->commit();
        }

        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="设置虚拟销量")
     * User: XMing
     * Date: 2020/9/3
     * Time: 10:43 上午
     * @param array $data
     * @return ResultWrapper
     */
    public function setSalesNum(array $data)
    {
        $updateResult = $this->objDGoods->update(['virtualSalesNum' => $data['val']],['id' => $data['id']]);
        if ($updateResult === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        /*
        $_id = self::createEsDocumentId($data['id']);
        $this->objDGoods->esupdateTypeFieldVaule(['virtualSalesNum' => $data['val']], $_id);*/
        return ResultWrapper::success(true);
    }


    /**
     * Doc: (des="批量设置运费")
     * User: XMing
     * Date: 2020/9/10
     * Time: 3:16 下午
     * @param array $params
     * @return ResultWrapper
     */
    public function batchGoodsExpress(array $params)
    {
        $ids = $params['ids'];
        $params['updateTime'] = time();
        unset($params['ids']);
        $updateResult = $this->objDGoods->update($params,['id'=>$ids]);
        if ($updateResult === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        foreach ($ids as $id){
            $_id = self::createEsDocumentId($id);
            $this->objDGoods->esupdateTypeFieldVaule($params, $_id);
        }
        return ResultWrapper::success(true);
    }

    /**
     * Doc: (des="根据商品ids获取所有商品")
     * User: XMing
     * Date: 2020/12/17
     * Time: 11:07 上午
     * @param array $goodsIds
     * @return ResultWrapper
     */
    public function getGoodsByGoodsIds(array $goodsIds,$shopId = 0): ResultWrapper
    {
        if (empty($goodsIds)){
            return ResultWrapper::success([]);
        }
        $goodsIdStr = implode(',',$goodsIds);
        if (empty($goodsIdStr)){
            return ResultWrapper::success([]);
        }
        $fields = ' g.id,g.enableStatus,b.title,b.images,b.id as materielId ';
        $sql = 'SELECT '.$fields.' FROM qianniao_goods_'.$this->enterpriseId.' AS g 
                LEFT JOIN qianniao_goods_basic_'.$this->enterpriseId.' AS b 
                ON b.id = g.basicGoodsId 
                WHERE b.deleteStatus = '.StatusCode::$standard.' AND g.deleteStatus = '.StatusCode::$standard.' AND 
                g.id IN('.$goodsIdStr.')';
        if (!empty($shopId)){
            $sql .= ' AND g.shopId = '.$shopId;
        }
        $lists = $this->objDGoods->query($sql);
        if ($lists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $map = [];
        foreach ($lists as $list){
            $list['images'] = !empty($list['images']) ? json_decode($list['images'],true) : [];
            $map[$list['id']] = $list;
        }
        return ResultWrapper::success($map);
    }


    /**
     * Doc: (des="根据基础物料id及店铺id,获取物料id对应商品id")
     * User: XMing
     * Date: 2020/12/25
     * Time: 4:03 下午
     * @param array $params
     * @return ResultWrapper
     */
    public function getRelMap(array $params): ResultWrapper
    {
        $materielStr = implode(',', $params['materielIds']);
        $fields = ' id AS goodsId,basicGoodsId AS materielId,shopId ';
        $sql = 'SELECT '.$fields.' FROM qianniao_goods_'.$this->enterpriseId.' 
                WHERE shopId = '.$params['shopId'].' 
                AND basicGoodsId IN ( '.$materielStr.') ';
        $lists = $this->objDGoods->query($sql);
        if ($lists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        $map = [];
        foreach ($lists as $list){
            $map[$list['materielId']] = $list['goodsId'];
        }
        return ResultWrapper::success($map);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/1/29
     * Time: 11:26 上午
     * @param int $shopId
     * @return ResultWrapper
     */
    public function getInSaleNum(int $shopId): ResultWrapper
    {
        $where = [
            'shopId' => $shopId,
            'enableStatus' => StatusCode::$standard,
            'deleteStatus' => StatusCode::$standard
        ];
        $count = $this->objDGoods->count($where);
        if($count === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        return ResultWrapper::success($count);
    }

    /**
     * Doc: (des="获取负库存销售状态")
     * User: XMing
     * Date: 2021/3/10
     * Time: 9:38 上午
     * @param int $shopId
     * @param array $materielIds
     * @return ResultWrapper
     */
    public function getDistributionByShopIdRelMaterielIds(int $shopId,array $materielIds): ResultWrapper
    {
        if (empty($shopId)){
            return ResultWrapper::fail('shopId参数异常',ErrorCode::$paramError);
        }
        if (empty($materielIds)){
            return ResultWrapper::fail('materielIds参数异常',ErrorCode::$paramError);
        }
        $fields = ' b.id,g.isDistribution ';
        $materielIdsStr = trim(implode(',',$materielIds),',');
        $sql = 'SELECT '.$fields.' FROM qianniao_goods_basic_'.$this->enterpriseId.' AS b 
                LEFT JOIN qianniao_goods_'.$this->enterpriseId.' AS g 
                ON g.basicGoodsId = b.id 
                WHERE g.basicGoodsId IN ('.$materielIdsStr.') AND g.shopId = '.$shopId;
        $lists = $this->objDGoods->query($sql);
        if ($lists === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        if (empty($lists)){
            return ResultWrapper::success([]);
        }
        $mapping = [];
        foreach ($lists as $item){
            $mapping[$item['id']] = $item['isDistribution'];
        }
        return ResultWrapper::success($mapping);
    }

    /**
     * Doc: (des="获取价格走势")
     * User: XMing
     * Date: 2021/3/10
     * Time: 6:48 下午
     * @param int $goodsId
     * @param array $params
     * @return ResultWrapper
     * @throws Exception
     */
    public function getPriceTrend(int $goodsId,array $params): ResultWrapper
    {
        $info = $this->objDGoods->get($goodsId);
        if ($info === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        if (empty($info)){
            return ResultWrapper::fail('未获取到指定的商品信息',ErrorCode::$paramError);
        }
        $objPriceCache = new PriceCache($this->enterpriseId);
        $objMPurchase = new MPurchase($this->userCenterId,$this->enterpriseId);
        $mapping = $objPriceCache->getPriceTrend($goodsId);
        if (!empty($mapping)){
            return ResultWrapper::success($mapping);
        }
        $skuLists = $this->objDSku->select(['goodsId' => $info['basicGoodsId'],'deleteStatus' => StatusCode::$standard],'id');
        if ($skuLists === false){
            return ResultWrapper::fail($this->objDSku->error(),ErrorCode::$dberror);
        }
        $skuIds = [];
        foreach ($skuLists as $item){
            $skuIds[] = $item['id'];
        }

        $mapping = [];
        $day = ceil(($params['endTime'] - $params['startTime']) / 86400);
        for($i = $day; $i>=0; $i--) {
            $date = strtotime(date('Y-m-d 23:59:59',strtotime("-$i days")));
            $sheetListsResult = $this->objMPrice->getPriceSheetByShopIdRelGoodsId($info['shopId'],$info['id'],$date);
            if (!$sheetListsResult->isSuccess()){
                return ResultWrapper::fail($sheetListsResult->getData(),$sheetListsResult->getErrorCode());
            }
            $sheetList = $sheetListsResult->getData();

            $costPriceSheetResult = $objMPurchase->getCostPriceSheetByMaterielId($info['basicGoodsId'],$date);
            if (!$costPriceSheetResult->isSuccess()){
                return ResultWrapper::fail($costPriceSheetResult->getData(),$costPriceSheetResult->getErrorCode());
            }
            $costPriceSheet = $costPriceSheetResult->getData();

            foreach ($skuIds as $skuId){
                $mapping['saleTrend'][$skuId][] = [
                    'salePrice' => isset($sheetList['salePrice'][$skuId]['salePrice']) ? $sheetList['salePrice'][$skuId]['salePrice'] : 0,
                    'createTime' => date('Y-m-d',$date),
                ];
                $mapping['costTrend'][$skuId][] = [
                    'costPrice'  => isset($costPriceSheet[$skuId][0]['costPrice']) ? $costPriceSheet[$skuId][0]['costPrice'] : 0,
                    'createTime' => date('Y-m-d',$date)
                ];
            }
        }
        return ResultWrapper::success($mapping);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/3/13
     * Time: 10:13 上午
     * @param array $data
     * @return ResultWrapper
     */
    public function batchSetDistribution(array $data): ResultWrapper
    {
        if (!in_array($data['isDistribution'],[ StatusCode::$delete,StatusCode::$standard ])){
            return ResultWrapper::fail('isDistribution参数非法',ErrorCode::$paramError);
        }
        $result = $this->objDGoods->update(['isDistribution' => $data['isDistribution'],'updateTime'=>time()],['id' => $data['ids']]);
        if ($result === false){
            return ResultWrapper::fail($this->objDGoods->error(),ErrorCode::$dberror);
        }
        return ResultWrapper::success(true);
    }

    /**
     * 获取商品数据
     * @param $where
     * @return ResultWrapper
     */
    public function getGoodsData($where)
    {
        $dbResult = $this->objDGoods->select($where);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        return ResultWrapper::success($dbResult);
    }


    /**
     * getAllBrandByCategory
     * 根据商品分类加载商品品牌
     * （1） select b1.categoryId,b1.categoryPath,b1.brandId,b2.* from qianniao_goods_basic_64 as b1 LEFT JOIN qianniao_goods_brand_64 as b2 on b1.brandId=b2.id where FIND_IN_SET(categoryPath,1)
     * （2） SELECT * from qianniao_goods_brand_64 where id in (SELECT brandId from qianniao_goods_basic_64 where FIND_IN_SET(categoryPath,1))
     */
    public function getAllBrandByCategory($categoryId)
    {
        $goodsBasic = new DGoodsBasic();
        $this->objDGoodsBasic->setTable($this->objDGoodsBasic->get_Table() . '_' . $this->enterpriseId);
        // 查询所有的该分类所有的商品品牌
        $sql = 'select * from qianniao_goods_brand_'.$this->enterpriseId.' where id in (SELECT brandId from qianniao_goods_basic_'.$this->enterpriseId.' where FIND_IN_SET(categoryPath,'.$categoryId.'))';
        $result = $goodsBasic->query($sql);
        if($result === false){
            return ResultWrapper::fail($goodsBasic->error(), ErrorCode::$dberror);
        }
        $countSql = 'select count(1) as count from qianniao_goods_brand_'.$this->enterpriseId.' where id in (SELECT brandId from qianniao_goods_basic_'.$this->enterpriseId.' where FIND_IN_SET(categoryPath,'.$categoryId.'))';
        $resultCount = $goodsBasic->query($countSql);
        if($resultCount === false){
            return ResultWrapper::fail($goodsBasic->error(), ErrorCode::$dberror);
        }
        if(empty($resultCount)){
            return ResultWrapper::success([]);
        }
        $data = [
            'data' => $result,
            'total' => $resultCount[0]['count'],
        ];
        return ResultWrapper::success($data);
    }


    /**
     * 商品真实销量
     */
    public function getAllRealSalesNum($params)
    {
        if( !isset($params['number'])&& empty($params['number'])){
            $params['number'] = 10;
        }

        $dbResult = $this->objDGoods->query('select * from '.$this->objDGoods->get_Table().' where enableStatus='.StatusCode::$standard.' and deleteStatus='.StatusCode::$standard.' order by realSalesNum desc limit 1,'.$params['number']);
        if($dbResult === false){
            return ResultWrapper::fail($this->objDGoods->error(), ErrorCode::$dberror);
        }
        if(!empty($dbResult)){
            foreach ($dbResult as $key => $value){
                if(isset($value['images'])&&!empty($value['images'])){
                    $dbResult[$key]['images'] = json_decode($value['images'],true);
                }
            }
        }
        $data = [
            'data' => $dbResult
        ];
        return ResultWrapper::success($data);
    }

}
