<?php

namespace JinDouYun\Model\Goods;

use JinDouYun\Cache\GoodsBasicCache;
use JinDouYun\Cache\GoodsBasicRelevant;
use Jindouyun\Cache\RoleAclCache;
use JinDouYun\Cache\SkuCache;
use JinDouYun\Controller\Common\Logger;
use JinDouYun\Dao\GoodsManage\DGoodsBasic;
use JinDouYun\Dao\GoodsManage\DSku;
use JinDouYun\Model\Commission\MCommissionSetting;
use JinDouYun\Model\GoodsManage\MGoodsBasic;
use JinDouYun\Model\GoodsManage\MSku;
use JinDouYun\Model\MBaseModel;
use JinDouYun\Model\Price\MCustomerPriceAdjustment;
use JinDouYun\Model\Price\MCustomerTypePriceAdjustment;
use JinDouYun\Model\Shop\MShop;
use JinDouYun\Model\Stock\MInventory;
use Mall\Framework\Core\ErrorCode;
use Mall\Framework\Core\ResultWrapper;
use Mall\Framework\Core\StatusCode;
use Util\Common\ChineseCharacter;
use const Grpc\STATUS_ABORTED;

class MQuickGoods extends MBaseModel
{
    /**
     * BasicAndSkuCache
     */
    use BasicAndSkuCache;

    /**
     * @var integer
     */
    private $onlineEnterpriseId;

    /**
     * @var integer
     */
    private $onlineUserId;

    /**
     * @var MGoods
     */
    private $objMGoods;

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

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

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

    private $objGoodsBasicCache;

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

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

    /**
     * @var GoodsBasicRelevant
     */
    private $objGoodsBasicRelevant;

    /**
     * @var SkuCache
     */
    private $objSkuCache;

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

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

    /**
     * MQuickGoods constructor.
     * @param $onlineEnterpriseId
     * @param $onlineUserId
     * @throws \Exception
     */
    public function __construct($onlineEnterpriseId, $onlineUserId)
    {
        $this->onlineEnterpriseId = $onlineEnterpriseId;
        $this->onlineUserId = $onlineUserId;
        parent::__construct($onlineEnterpriseId, $onlineUserId);
        $this->objMGoods = new MGoods($this->onlineEnterpriseId, false, $this->onlineUserId);
        $this->objMGoodsBasic = new MGoodsBasic($this->onlineUserId, $this->onlineEnterpriseId);
        $this->objDGoodsBasic = new DGoodsBasic();
        $this->objDGoodsBasic->setTable('qianniao_goods_basic_'.$this->onlineEnterpriseId);
        $this->objDSku = new DSku();
        $this->objMSku = new MSku($this->onlineUserId,$this->onlineEnterpriseId);
        $this->objMShop = new MShop($this->onlineEnterpriseId,$this->onlineUserId);
        $this->objMInventory  = new MInventory($this->onlineEnterpriseId,$this->onlineUserId);
        $this->objDSku->setTable('qianniao_sku_'.$this->onlineEnterpriseId);
        $this->objGoodsBasicCache = new GoodsBasicCache($this->onlineEnterpriseId);
        $this->objGoodsBasicRelevant = new GoodsBasicRelevant($this->onlineEnterpriseId);
        $this->objSkuCache =  new SkuCache($this->onlineEnterpriseId);
        $this->objMCommissionSetting = new MCommissionSetting($this->onlineEnterpriseId,$this->onlineUserId);
    }

    /**
     * @param $params
     * @return ResultWrapper
     * @throws \Exception
     */
    public function addBasicAndPublishGoods($params)
    {

        $goodsBasic = [
            'title'        => $params['title'],
            'categoryId'   => $params['categoryId'],
            'categoryPath' => $params['categoryPath'],
            'assistCategoryId'   => $params['assistCategoryId'],
            'assistCategoryPath' => $params['assistCategoryPath'],
            'images'       => $params['images'],
            'specType'     => $params['specType'],
            'brandId'      => $params['brandId'],
            'description'  => $params['description'],
            'describe'     => $params['describe'],
            'expireTime'   => $params['expireTime'],
            'tag'          => $params['tag'],
            'barCode'      => $params['barCode'],
            'link'         => $params['link'],
            'noSalesShop'  => $params['noSalesShop'],
            'specGroup'    => $params['specGroup'],
            'extends'      => getArrayItem($params, 'extends', '[]'),
            'supplierId'   => getArrayItem($params,'supplierId',0),
            'isEq'         => getArrayItem($params,'isEq',StatusCode::$delete),
            'merchantId'   => $params['merchantId'],
        ];
        if (isset($params['isStore']) && $params['isStore'] == true){
            $goodsBasic['storeId'] = $params['shopId'];//发布此商品的商户id
            $goodsBasic['level'] = StatusCode::$delete;//商户级别商品
        }
        $dbResult = self::addQuickGoodsBasic($params,$goodsBasic,$params['unitData'],$params['specMultiple']);
        if (!$dbResult ->isSuccess()){
            return ResultWrapper::fail($dbResult->getData(),$dbResult->getErrorCode());
        }
        return ResultWrapper::success($dbResult);
    }

    /**
     * @param $params
     * @param $goodsBasic
     * @param $unitData
     * @param $specMultiple
     * @return ResultWrapper
     * @throws \Exception
     */
    public function addQuickGoodsBasic($params,$goodsBasic, $unitData, $specMultiple)
    {
        $goodsBasic['addUserId'] = $this->onlineUserId;//创建人id
        $objRoleAclCache = new RoleAclCache();
        $staffId = $objRoleAclCache->getStaffIdAndUserCenterId($this->onlineEnterpriseId, $this->onlineUserId);
        $goodsBasic['salesManId'] = empty($staffId) ? 0 : $staffId;

        //商品名称转换搜索条件
        $objChineseCharacter = new ChineseCharacter();
        $goodsBasic['condition'] = $objChineseCharacter->getInitials(trim($params['title']));

        $this->objDGoodsBasic->beginTransaction();
        $dbResult = $this->objDGoodsBasic->insert($goodsBasic);

        if ($dbResult === false) {
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($this->objDGoodsBasic->error(), ErrorCode::$dberror);
        }
        $goodsBasicId = $dbResult;

        $skuInsert = [];
        foreach ($specMultiple as $key => $item) {
            $skuInsert[$key] = [
                'goodsId'    => $goodsBasicId,
                'conversion' => isset($item['conversion']) ? $item['conversion'] : 0,
                'unitId'     => $item['unitId'],
                'unitName'   => $item['unitName'],
                'isMaster'   => $item['isMaster'],
                'createTime' => time(),
                'specType'   => $params['specType'],
                'barCode'    => isset($item['barCode']) ? $item['barCode'] : '',
                'isDefault'  => isset($item['isDefault']) ?  $item['isDefault'] : StatusCode::$delete,
                'weight'      => isset($item['weight']) ?  $item['weight'] : 0,
                'isNew'      => StatusCode::$standard,
            ];
            if ($params['specType'] == StatusCode::$specType['multiple']){
                $specGroupIds = array_column($item['specGroup'], 'specValueId');
                $hash = md5(implode('|', $specGroupIds));
                $skuInsert[$key]['specImage'] = json_encode($item['specImage']);
                $skuInsert[$key]['specGroupHash'] = $hash;
                $skuInsert[$key]['specData'] = json_encode($item['specGroup']);
            }
        }

        //添加sku
        $skuResult =$this->objDSku->insert($skuInsert,true);
        if ($skuResult === false) {
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
        }
        //缓存sku
        $this->updateSku = $skuResult;
        $this->isUpdateSku = true;

        //缓存商品分类下基础商品数量
        $categoryIds = explode(',', $params['categoryPath']);
        foreach ($categoryIds as $v) {
            $this->objGoodsBasicCache->categoryKeyScoreIncr($v);
        }
        $this->objGoodsBasicCache->brandKeyScoreIncr($params['brandId']);
        //缓存基础商品数据
        $this->isUpdateBasicCache = true;
        $this->objectId = $goodsBasicId;
        //操作es
        //$this->objMGoodsBasic->updateEsData($goodsBasicId);

        //将sku写入salePrice中
        $priceData = [];
        $customerPrices = [];//客户调价
        $customerTypePrices = [];//客户类型调价
        $skuResult = (array) $skuResult;
        foreach ($skuResult as $key => $id){
            if (!isset($specMultiple[$key])){
                continue;
            }
            $thisSalePrice = null;
            $thisSalePrice = $specMultiple[$key]['salePrice'];
            $thisSalePrice['id'] = $id;
            $priceData[] = $thisSalePrice;

            $thisCustomerPrice = null;
            $thisCustomerPrice = isset($specMultiple[$key]['customerPrice']) ? $specMultiple[$key]['customerPrice'] : [];
            if (!empty($thisCustomerPrice)){
                self::pushVal($thisCustomerPrice,$id,'skuId');
                $customerPrices[] = $thisCustomerPrice;
            }

            $thisCustomerTypePrice = null;
            $thisCustomerTypePrice = isset($specMultiple[$key]['customerTypePrice']) ? $specMultiple[$key]['customerTypePrice'] : [];
            if (!empty($thisCustomerTypePrice)){
                self::pushVal($thisCustomerTypePrice,$id,'skuId');
                $customerTypePrices[] = $thisCustomerTypePrice;
            }
        }




        $goods = [
            'basicGoodsId' => $goodsBasicId,
            'merchantId'   => getArrayItem($params, 'merchantId', 0),
            'goodsName'    => $params['title'],
            'shopId'       => $params['shopId'],
            'staffId'      => $goodsBasic['addUserId'],
            'shopName'     => $params['shopName'],//商铺名称
            'images'       => $params['images'],
            'specType'     => $params['specType'],//规格类型
            'enableStatus' => getArrayItem($params, 'enableStatus', StatusCode::$delete),
            'priceData'    => $priceData,
            'createUserName' => $params['createUserName'],
            'content'     => $params['description'],
            'isRecommend' => StatusCode::$standard,
            'sort'        => $params['sort'],
            'deleteStatus'=> StatusCode::$standard,
            'createTime'  => time(),
            'supplierId'  => getArrayItem($params,'supplierId',0),
            'isShield'    => getArrayItem($params,'isShield',0),
            'notArea'     => getArrayItem($params,'notArea',''),
            'notCustomerType' => getArrayItem($params,'notCustomerType',''),
            'notCustomer' => getArrayItem($params,'notCustomer',''),
            'isDistribution' => getArrayItem($params,'isDistribution',StatusCode::$delete),
        ];
        if (isset($params['isStore']) && $params['isStore'] == true){
            $goods['auditStatus'] = StatusCode::$auditStatus['auditing'];//正在审核
            $goods['enableStatus'] = StatusCode::$delete;//下架状态
            $goods['isOption'] = StatusCode::$standard;//自选商品
        }
        isset($params['deliverySupIds']) && $goods['deliverySupIds'] = $params['deliverySupIds'];
        isset($params['expressType']) && $goods['expressType'] = $params['expressType'];
        isset($params['ruleId']) && $goods['ruleId'] = $params['ruleId'];
        isset($params['expressFee']) && $goods['expressFee'] = $params['expressFee'];
        isset($params['showExpress']) && $goods['showExpress'] = $params['showExpress'];

        $commissionResult = $this->objMCommissionSetting->getSetting('goods');
        if (!$commissionResult->isSuccess()){
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($commissionResult->getData(),$commissionResult->getErrorCode());
        }

        $goods['isJoinCommission'] = !empty($commissionResult->getData()) ? $commissionResult->getData() : StatusCode::$delete;
        //将数据写入商品表
        $goodsResult = $this->objMGoods->addGoods($goods);
        if (!$goodsResult->isSuccess()){
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($goodsResult->getData(), $goodsResult->getErrorCode());
        }

        $params['goodsId'] = (int)$goodsResult->getData();
        if (!empty($customerPrices)){
            //生成客户调价单
            $buildCustomerPrice = self::buildCustomerPrice($customerPrices,$params);
            $objMCustomerPriceAdjustment = new MCustomerPriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
            $adjustmentResult = $objMCustomerPriceAdjustment->add($buildCustomerPrice);
            if (!$adjustmentResult->isSuccess()){
                Logger::logs(E_USER_ERROR,'add',__CLASS__,__LINE__,$adjustmentResult->getData());
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
            }
            $sheetIds = $adjustmentResult->getData();
            foreach ($sheetIds as $key => $id){
                $row = getArrayItem($buildCustomerPrice,$key,[]);
                $effectiveResult = $objMCustomerPriceAdjustment->effective($id,$row);
                if (!$effectiveResult->isSuccess()){
                    $this->objDGoodsBasic->rollBack();
                    return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
                }
            }
        }

        if (!empty($customerTypePrices)){
            //生成客户类型调价
            $buildCustomerTypePrice = self::buildCustomerTypePrice($customerTypePrices,$params);
            $objMCustomerTypePriceAdjustment = new MCustomerTypePriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
            $adjustmentResult = $objMCustomerTypePriceAdjustment->add($buildCustomerTypePrice);
            if (!$adjustmentResult->isSuccess()){
                Logger::logs(E_USER_ERROR,'add',__CLASS__,__LINE__,$adjustmentResult->getData());
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
            }
            $sheetIds = $adjustmentResult->getData();
            foreach ($sheetIds as $key => $id){
                $row = getArrayItem($buildCustomerTypePrice,$key,[]);
                $effectiveResult = $objMCustomerTypePriceAdjustment->effective($id,$row);
                if (!$effectiveResult->isSuccess()){
                    $this->objDGoodsBasic->rollBack();
                    return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
                }
            }
        }


        $this->objDGoodsBasic->commit();
        $this->objGoodsBasicCache->brandKeyScoreIncr($params['brandId']);
        return ResultWrapper::success($goodsResult);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/3/25
     * Time: 4:22 下午
     * @param array $params
     * @param array $common
     * @return array
     */
    private function buildCustomerPrice(array $params,array $common): array
    {
        if (empty($params)){
            return [];
        }

        $line = [
            "createUserName" => getArrayItem($common,'createUserName',''),
            "goodsName" => getArrayItem($common,'title',''),
            'goodsCode' => createCode(StatusCode::$code['goodsBasic']['prefix'], $common['goodsId'], StatusCode::$code['goodsBasic']['length']),
            "goodsId" => getArrayItem($common,'goodsId',0),
            "shopId" => getArrayItem($common,'shopId',0),
            "shopName" => getArrayItem($common,'shopName',''),
            'createTime' => time(),
            'updateTime' => time()
        ];
        $map = [];
        foreach ($params as $key => $items){
            foreach ($items as $row){
                $salePrice[$row['customerId']][] = [
                    "price" => $row['price'],
				    "skuId" =>  $row['skuId'],
				    "unitName" => getArrayItem($row,'unitName',''),
				    "adjPricetag" => $row['adjPricetag']
                ];
                $map[$row['customerId']] = [
                    "customerName" => getArrayItem($row,'customerName',''),
		            "customerId"   => getArrayItem($row,'customerId',0),
                    "salePrice"    => json_encode($salePrice[$row['customerId']])
                ];
            }
        }

        foreach ($map as &$value){
            $value = array_merge($value,$line);
        }
        return array_values($map);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2021/3/25
     * Time: 5:00 下午
     * @param array $params
     * @param array $common
     * @return array
     */
    private function buildCustomerTypePrice(array $params,array $common): array
    {
        if (empty($params)){
            return [];
        }

        $line = [
            "createUserName" => getArrayItem($common,'createUserName',''),
            "goodsName" => getArrayItem($common,'title',''),
            "goodsId" => getArrayItem($common,'goodsId',0),
            'goodsCode' => createCode(StatusCode::$code['goodsBasic']['prefix'], $common['goodsId'], StatusCode::$code['goodsBasic']['length']),
            "shopId" => getArrayItem($common,'shopId',0),
            "shopName" => getArrayItem($common,'shopName',''),
            'createTime' => time(),
            'updateTime' => time()
        ];
        $map = [];
        foreach ($params as $key => $items){
            foreach ($items as $row){
                $salePrice[$row['customerType']][] = [
                    "price" => $row['price'],
                    "skuId" =>  $row['skuId'],
                    "unitName" => getArrayItem($row,'unitName',''),
                    "adjPricetag" => $row['adjPricetag']
                ];
                $map[$row['customerType']] = [
                    "customerName" => getArrayItem($row,'customerName',''),
                    "customerType"   => getArrayItem($row,'customerType',0),
                    "salePrice"    => json_encode($salePrice[$row['customerType']])
                ];
            }
        }

        foreach ($map as &$value){
            $value = array_merge($value,$line);
        }
        return array_values($map);
    }

    /**
     * Doc: (des="")
     * User: XMing
     * Date: 2020/12/18
     * Time: 3:08 下午
     * @param $originArr
     * @param $val
     * @param string $field
     * @param bool $mul
     * @return void
     */
    private function pushVal(&$originArr, $val,$field = 'orderId', $mul = false)
    {
        if (empty($originArr)){
            return;
        }
        $map = [];
        foreach ($originArr as $key => &$item) {
            if ($mul === false) {
                $item[$field] = $val;
                continue;
            }
            foreach ($item as &$value) {
                $value[$field] = $val;
                $map[] = $value;
            }
        }
        $mul === true && $originArr = $map;
        $originArr = array_values($originArr);
    }

    /**
     * @param int $goodsId
     * @return ResultWrapper
     * @throws \Exception
     */
    public function getQuickGoodsInfo(int $goodsId)
    {
        $goodsResult = $this->objMGoods->getGoodsInfo($goodsId);

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

        $format = self::format($goodsResult->getData());
        $format = self::getSkuInventorySpec($format);

        return ResultWrapper::success($format);
    }

    /**
     * @param $data
     * @return mixed
     */
    public static function format($data)
    {
        if (empty($data)){
            return $data;
        }
        $data['description'] = $data['content'];
        $specMultiple = $data['specMultiple'];
        foreach ($specMultiple as &$spec){
            $spec['salePrice'] = [
                'id' => $spec['id'],
                'conversion' => $spec['conversion'],
                "unitName"=> $spec['unitName'],
				"unitId"=> $spec['unitId'],
				"isMaster"=> $spec['isMaster'],
				"deleteStatus"=> StatusCode::$delete,
				"enabledLadder"=> $spec['enabledLadder'],
				"salePriceAreaType"=> 1,
				"salePrice"=> $spec['salePrice'],
				"ladderPrice"=> $spec['ladderPrice'],
				"marketPrice"=> $spec['marketPrice'],
				"setNum"=> $spec['setNum']
            ];
        }
        $data['specMultiple'] = $specMultiple;
        return $data;
    }

    /**
     * @param $data
     * @return mixed
     */
    private function getSkuInventorySpec(array $data)
    {
        //查询物料库存
        $materielResult = $this->objMInventory->getInventoryByMaterielIds([$data['basicGoodsId']]);
        $materielMap = [];
        if (!$materielResult->isSuccess()){
            file_put_contents('/www/wwwroot/logs/api.junhailan.com/MQuickGoods_error.log', date('Y-m-d H:i:s') . '错误信息|sql错误 ：' . var_export($materielResult->getData()) . PHP_EOL, FILE_APPEND);
        }else{
            $materielMap = $materielResult->getData();
        }
        if (!isset($materielMap[$data['basicGoodsId']])){
            //从来没有采购过
            $data['isEditSpec'] = StatusCode::$standard;
        }else{
            //采购过
            $data['isEditSpec'] = StatusCode::$delete;
        }
        return $data;
    }

    /**
     * @param array $params
     * @param int $goodsId
     * @param int $basicGoodsId
     * @return ResultWrapper
     * @throws \Exception
     */
    public function editQuickGoods(array $params,int $goodsId,int $basicGoodsId)
    {
        $goodsBasic = [
            'title'        => $params['title'],
            'assistCategoryId'   => $params['assistCategoryId'],
            'assistCategoryPath' => $params['assistCategoryPath'],
            'categoryId'   => $params['categoryId'],
            'categoryPath' => $params['categoryPath'],
            'images'       => $params['images'],
            'specType'     => $params['specType'],
            'brandId'      => $params['brandId'],
            'description'  => $params['description'],
            'describe'     => $params['describe'],
            'expireTime'   => $params['expireTime'],
            'tag'          => $params['tag'],
            'barCode'      => $params['barCode'],
            'link'         => $params['link'],
            'noSalesShop'  => $params['noSalesShop'],
            'specGroup'    => $params['specGroup'],
            'extends'      => $params['extends'],
            'condition'    => $params['condition'],
            'isEq'         => $params['isEq']
        ];

        //商品名称转换搜索条件
        if(isset($goodsBasic['title'])){
            $objChineseCharacter = new ChineseCharacter();
            $goodsBasic['condition'] = $objChineseCharacter->getInitials(trim($goodsBasic['title']));
        }

        $priceData = [];
        $customerPrices = [];//客户调价
        $customerTypePrices = [];//客户类型调价

        $this->objDGoodsBasic->beginTransaction();
        //1.编辑基础资料
        $updateResult = $this->objDGoodsBasic->update($goodsBasic,['id'=> $basicGoodsId]);
        if ($updateResult === false){
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($this->objDGoodsBasic->error(),ErrorCode::$dberror);
        }

        //编辑sku
        $dbResult = self::commonMerge($params['specMultiple'],$basicGoodsId,$params['specType']);
        if (!$dbResult->isSuccess()) {
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($dbResult->getData(), $dbResult->getErrorCode());
        }
        $groupData = $dbResult->getData();

        if (!empty($groupData['insert'])){
            $format = self::formatMapPriceAndSku($groupData['insert']);
            $skuResult = $this->objDSku->insert($format['sku'],true);
            if ($skuResult === false){
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($this->objDSku->error(),ErrorCode::$dberror);
            }
            $this->updateSku = array_merge($this->updateSku,$skuResult);
            $skuResult = (array) $skuResult;

            foreach ($skuResult as $key => $id){
                if (!isset($format['salePrice'][$key])){
                    continue;
                }
                $thisSalePrice = null;
                $thisSalePrice = $format['salePrice'][$key];
                $thisSalePrice['id'] = $id;
                $priceData = array_merge($priceData,[$thisSalePrice]);


                $thisCustomerPrice = null;
                $thisCustomerPrice = isset($specMultiple[$key]['customerPrice']) ? $specMultiple[$key]['customerPrice'] : [];
                if (!empty($thisCustomerPrice)){
                    self::pushVal($thisCustomerPrice,$id,'skuId');
                    $customerPrices[] = $thisCustomerPrice;
                }

                $thisCustomerTypePrice = null;
                $thisCustomerTypePrice = isset($specMultiple[$key]['customerTypePrice']) ? $specMultiple[$key]['customerTypePrice'] : [];
                if (!empty($thisCustomerTypePrice)){
                    self::pushVal($thisCustomerTypePrice,$id,'skuId');
                    $customerTypePrices[] = $thisCustomerTypePrice;
                }
            }
        }

        if (!empty($groupData['update'])){
            $format = self::formatMapPriceAndSku($groupData['update']);
            $priceData = array_merge($priceData,$format['salePrice']);//商品价格数据
            $customerPrices = array_merge($customerPrices, $format['customerPrice']);
            $customerTypePrices = array_merge($customerTypePrices, $format['customerTypePrice']);
            foreach ($format['sku'] as &$spec) {
                unset($spec['hash']);
                $skuResult = $this->objDSku->update($spec, ['id' => $spec['id']]);
                $this->updateSku = array_merge($this->updateSku,[$spec['id']]);
            }
            if ($skuResult === false) {
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
            }
        }

        if (!empty($groupData['delete'])){
            $format = self::formatMapPriceAndSku($groupData['delete']);
            $skuResult = $this->objDSku->update(
                [
                    'deleteStatus' => StatusCode::$delete
                ],
                [
                    'id' => array_column($format['sku'], 'id')
                ]);
            if ($skuResult === false) {
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
            }
        }

        //3.缓存基础资料
        $this->isUpdateBasicCache = true;
        $this->isUpdateSku = true;
        $this->objectId = $basicGoodsId;

        //4.更新es
        $this->objMGoodsBasic->updateEsData($basicGoodsId);

        //5.编辑商品
        $goods = [
            'id'           => $goodsId,
            'basicGoodsId' => $basicGoodsId,
            'goodsName'    => $params['title'],
            'shopId'       => $params['shopId'],
            'shopName'     => $params['shopName'],//商铺名称
            'images'       => $params['images'],
            'specType'     => $params['specType'],//规格类型
            'enableStatus' => $params['enableStatus'],
            'priceData'    => $priceData,
            'createUserName' => $params['createUserName'],
            'content'     => $params['description'],
            'isRecommend' => StatusCode::$standard,
            'sort'        => $params['sort'],
            'deleteStatus'=> StatusCode::$standard,
            'updateTime'  => time(),
            'isShield'    => getArrayItem($params,'isShield',0),
            'notArea'     => getArrayItem($params,'notArea',''),
            'notCustomerType' => getArrayItem($params,'notCustomerType',''),
            'notCustomer' => getArrayItem($params,'notCustomer',''),
            'isDistribution' => getArrayItem($params,'isDistribution',StatusCode::$delete)
        ];
        isset($params['deliverySupIds']) && $goods['deliverySupIds'] = $params['deliverySupIds'];
        isset($params['expressType']) && $goods['expressType'] = $params['expressType'];
        isset($params['ruleId']) && $goods['ruleId'] = $params['ruleId'];
        isset($params['expressFee']) && $goods['expressFee'] = $params['expressFee'];
        isset($params['showExpress']) && $goods['showExpress'] = $params['showExpress'];

        $goodsResult = $this->objMGoods->editGoods($goods);
        if (!$goodsResult->isSuccess()){
            $this->objDGoodsBasic->rollBack();
            return ResultWrapper::fail($goodsResult->getData(),$goodsResult->getErrorCode());
        }

        $params['goodsId'] = $goodsId;
        if (!empty($customerPrices)){
            //生成客户调价单
            $buildCustomerPrice = self::buildCustomerPrice($customerPrices,$params);
            $objMCustomerPriceAdjustment = new MCustomerPriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
            $adjustmentResult = $objMCustomerPriceAdjustment->add($buildCustomerPrice);
            if (!$adjustmentResult->isSuccess()){
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
            }
            $sheetIds = $adjustmentResult->getData();
            foreach ($sheetIds as $key => $id){
                $row = getArrayItem($buildCustomerPrice,$key,[]);
                $effectiveResult = $objMCustomerPriceAdjustment->effective($id,$row);
                if (!$effectiveResult->isSuccess()){
                    $this->objDGoodsBasic->rollBack();
                    return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
                }
            }
        }

        if (!empty($customerTypePrices)){
            //生成客户类型调价
            $buildCustomerTypePrice = self::buildCustomerTypePrice($customerTypePrices,$params);
            $objMCustomerTypePriceAdjustment = new MCustomerTypePriceAdjustment($this->onlineUserId,$this->onlineEnterpriseId);
            $adjustmentResult = $objMCustomerTypePriceAdjustment->add($buildCustomerTypePrice);
            if (!$adjustmentResult->isSuccess()){
                $this->objDGoodsBasic->rollBack();
                return ResultWrapper::fail($adjustmentResult->getData(),$adjustmentResult->getErrorCode());
            }
            $sheetIds = $adjustmentResult->getData();
            foreach ($sheetIds as $key => $id){
                $row = getArrayItem($buildCustomerTypePrice,$key,[]);
                $effectiveResult = $objMCustomerTypePriceAdjustment->effective($id,$row);
                if (!$effectiveResult->isSuccess()){
                    $this->objDGoodsBasic->rollBack();
                    return ResultWrapper::fail($effectiveResult->getData(),$effectiveResult->getErrorCode());
                }
            }
        }

        $this->objDGoodsBasic->commit();
        $this->objMSku->delSkuCache($basicGoodsId);
        return ResultWrapper::success($goodsResult);
    }

    /**
     * @param $data
     * @return array
     */
    private static function formatMapPriceAndSku(array $data)
    {
        if (empty($data)){
            return [];
        }

        $map = [];
        $map['customerPrice'] = [];
        $map['customerTypePrice'] = [];
        foreach ($data as &$row){
            $map['salePrice'][] = $row['salePrice'];
            unset($row['salePrice']);
            if(isset($row['customerPrice'])){
                $map['customerPrice'][] = $row['customerPrice'];
                unset($row['customerPrice']);
            }

            if(isset($row['customerTypePrice'])){
                $map['customerTypePrice'][] = $row['customerTypePrice'];
                unset($row['customerTypePrice']);
            }

            $map['sku'][] = $row;
        }
        return $map;
    }

    /**
     * @param array $specMultiple
     * @param int $basicGoodsId
     * @return ResultWrapper
     */
    public function commonMerge(array $specMultiple, int $basicGoodsId,int $specType)
    {
        $isNewResult = $this->objMSku->getIsNewByGoodsId($basicGoodsId);
        if (!$isNewResult->isSuccess()){
            return ResultWrapper::fail($isNewResult->getData(),$isNewResult->getErrorCode());
        }
        $isNew = $isNewResult->getData();

        // 查询当前商品所有sku数据
        $skuResult = $this->objDSku->select(['goodsId'=>$basicGoodsId,'deleteStatus'=>StatusCode::$standard]);
        if ($skuResult === false) {
            return ResultWrapper::fail($this->objDSku->error(), ErrorCode::$dberror);
        }
        if (empty($skuResult)){
            return ResultWrapper::success([]);
        }

        //1.对旧数据生成hash
        $mapping = [];
        $allHash = [];
        foreach ($skuResult as &$value) {
            $hash = md5($value['goodsId'] . $value['unitId'] . $value['isMaster'] . $value['specGroupHash']);
            $value['hash'] = $hash;
            $mapping[$value['hash']] = $value;
            $allHash[] = $value['hash'];
        }

        //2.对现在数据生成hash
        $nowData = [];
        foreach ($specMultiple as $key => $spec){
            if (!empty($spec['specGroup'])){
                $specGroupIds = array_column($spec['specGroup'], 'specValueId');
                $specGroupHash = md5(implode('|', $specGroupIds));//属性hash值
            }else{
                $specGroupHash = '';
            }
            $hash = md5($basicGoodsId . $spec['unitId'] . $spec['isMaster'] . $specGroupHash);//对单行数据生成hash值
            $nowData[$key] = [
                'goodsId'       => $basicGoodsId,
                'specData'      => empty($spec['specGroup']) ?  null : json_encode($spec['specGroup']),
                'specImage'     => empty($spec['specImage']) ? null : json_encode([$spec['specImage']]),
                'specType'      => $specType,
                'unitId'        => $spec['unitId'],
                'isMaster'      => $spec['isMaster'],
                'unitName'      => $spec['unitName'],
                'conversion'    => $spec['conversion'],
                'specGroupHash' => $specGroupHash,
                'hash'          => $hash,
                'barCode'       => isset($spec['barCode']) ? $spec['barCode'] : '',
                'isDefault'     => isset($spec['isDefault']) ? $spec['isDefault'] : StatusCode::$delete,
                'weight'         => isset($spec['weight']) ? $spec['weight'] : 0,
                'salePrice'     => $spec['salePrice'],
                'isNew'        => $isNew
            ];//新的数据

            if(!empty($spec['customerPrice'])){
                $nowData[$key]['customerPrice'] = $spec['customerPrice'];
            }
            if(!empty($spec['customerTypePrice'])){
                $nowData[$key]['customerTypePrice'] = $spec['customerTypePrice'];
            }

        }
        unset($spec);

        //3.比对数据
        $insert = [];
        $update = [];
        $delete = [];
        foreach ($nowData as &$spec) {
            if (in_array($spec['hash'], $allHash)) {
                $spec['id'] = $mapping[$spec['hash']]['id'];
                $spec['salePrice']['id'] = $mapping[$spec['hash']]['id'];//价格信息+skuId
                if( isset($spec['customerPrice']) ){
                    foreach ($spec['customerPrice'] as $key => $value){
                        $spec['customerPrice'][$key]['skuId'] = $mapping[$spec['hash']]['id'];
                    }
                }
                if( isset($spec['customerTypePrice']) ){
                    foreach ($spec['customerTypePrice'] as $key => $value){
                        $spec['customerTypePrice'][$key]['skuId'] = $mapping[$spec['hash']]['id'];
                    }
                }
                $update[] = $spec;
                unset($mapping[$spec['hash']]);
            } else {
                unset($spec['hash']);
                $insert[] = $spec;
            }
        }
        return ResultWrapper::success([
            'insert' => $insert,
            'update' => $update,
            'delete' => array_values($mapping),
        ]);
    }

    /**
     * @return ResultWrapper
     */
    public function getShopData()
    {
        $shopResult = $this->objMShop->getScopeShopInfo($this->onlineEnterpriseId,'id,name');
        if (!$shopResult->isSuccess()){
            return ResultWrapper::fail($shopResult->getData(),$shopResult->getErrorCode());
        }
        return ResultWrapper::success($shopResult->getData());
    }

    /**
     * @After
     * 缓存基础资料数据
     */
    public function __destruct()
    {
        // TODO: Implement __destruct() method.
        self::cacheBasic();
        self::cacheSku();
    }

}