zoukankan      html  css  js  c++  java
  • Shopify 接口调用

    <?php
    /**
     * Created by PhpStorm.
     * User: lxd
     * Date: 2019/12/30
     * Time: 11:22
     * Comm:
     */
    namespace ApiController;
    
    use CommonLibTsTsPackage;
    use CommonLogicCountryLogic;
    use CommonLogicDeviceLogic;
    use CommonLogicGoodsLogic;
    use CommonLogicIslandLogic;
    use CommonLogicPartnerGoodsOrderLogic;
    use CommonLogicPartnerGoodsSonorderLogic;
    use CommonLogicPartnerLogic;
    use CommonLogicSimcardLogic;
    use CommonModelDataPackageModel;
    use CommonModelGoodsModel;
    use CommonModelPartnerModel;
    use PartnerLogicLeaseLogic;
    use ThinkController;
    use ThinkException;
    use ThinkLog;
    use ThinkModel;
    
    class ShopifyNoticeController extends Controller
    {
        private $_param;
        private $_paramArr;
        private $_header    = [
            'HTTP_X_SHOPIFY_TEST'   => 'false',
            'HTTP_X_SHOPIFY_HMAC_SHA256'    => '',
        ];
        private $_logque;
        private $_sign      = '33ee5426dad7acd783862018ec04af35069f2ed0f913b2ff486f95432b2e02f7';
        private $_self_partner  = 1; //shopify的合作商id,订单归属合作商
        private $_partner;
        private $_api       = [
            'key'   => '951d7d219e283094adf901a6640a8a42',
            'pwd'   => '207fe05963cc8c4a8559c65ecec3e417',
            'url'   => 'test-uro.myshopify.com/admin/api/',
            'version'    => '2020-01',
            'authorization'     => ''
        ];
        private $_curl;
        private $_cityToCollectionRedisKey  = "ShopifyNotice:cityToCollection";
    //    private $_productToCoolectRedisKey  = "ShopifyNotice:productToCoolect";
        private $_productStatus             = "ShopifyNotice:productStatus";
        private $_productToArea             = "ShopifyNotice:productToArea"; //最后一个逗号值是商品类型
        private $_shopifyCurlQueue          = "ShopifyNotice:curlQueue"; //curl放队列里面 单个执行
        private $_curlLastErr   = '';
        private $_skipCheckHeaderAction     = ['getcustomcollections'];
    
        const DEVICEFLOW    = 'DEVICE_FLOW'; //设备流量
        const SIMFLOW       = 'SIM_FLOW'; //sim流量
        const SIMOTAFLOW    = 'SIM_FLOW_AND_OTA_CARD'; //sim流量 + ota卡
        const SIMONCEFLOW   = 'SIM_FLOW_AND_ONCE_CARD'; //sim流量 + 非ota卡
        CONST ESIM          = 'ESIM'; //esim 类型
    
        const TAGOTA        = 'plus ota card';
        const TAGONCE       = 'plus once card';
    
        const HANDLESIM     = 2;
        CONST HANDLEDEVICE  = 3;
        CONST HANDLEOTA     = 4;
        CONST HANDLEONCE    = 5;
        CONST HANDLE_ESIM    = 6;
    
        public function __construct( $skipPartner = false )
        {
            parent::__construct();
    
            $this->_param   = file_get_contents( 'php://input' );
            $this->_paramArr    = json_decode( $this->_param, true );
            $this->_header  = $_SERVER;
            if( $this->_param )
                $this->_setLog( "receive param == {$this->_param}, header == " . json_encode( $this->_header ) );
            
            if( !APP_DEBUG ) {
                $this->_sign        = '//online data';
                $this->_api       = [
                    //online shopify api data
                ];
            }
            $this->_curl    = new Curl();
            $this->_api['authorization']    = base64_encode( "{$this->_api['key']}:{$this->_api['pwd']}" );
    
            if( !in_array( strtolower( ACTION_NAME ), $this->_skipCheckHeaderAction ) )
                $this->_checkParam();
        }
    
        public function getCurlQueueName()
        {
            return $this->_shopifyCurlQueue;
        }
    
        public function getCustomCollections( $param )
        {
            if( !isset( $param['ids'] ) ) {
                return [];
            }
    
            $proIds     = explode( ',', $param['ids'] );
            array_filter( $proIds );
    
            if( empty( $proIds ) ) 
                return [];
    
            //读取商品对应的city ids
            $redis  = getRedis();
            $reret  = $redis->hMGet( $this->_productToArea, $proIds );
            if( empty( $reret ) )
                return [];
    
            $cityToCollection       = [];
            $tempCityToCollection   = $redis->hGetAll( $this->_cityToCollectionRedisKey );
            foreach( $tempCityToCollection as $cid => $collInfo ) {
                $tempCollInfo   = json_decode( $collInfo,true );
                if( empty( $tempCollInfo ) )
                    continue;
                $cityToCollection[$cid]     = $tempCollInfo['id'];
            }
    
            $return     = [];
            foreach( $reret as $pid => $areas ) {
                $tempArea   = explode(',', $areas );
                array_pop( $tempArea ); //弹出商品类型
    
                if( count( $tempArea  )  < 1 ) //出错了,忽略掉
                    continue;
    
                $tempAreaCollIds    = [];
                foreach( $tempArea as $_cid ) {
                    if( isset( $cityToCollection[$_cid] ) ) {
                        $tempAreaCollIds[]  = $cityToCollection[$_cid];
                    }
                }
    
                $return[$pid]    = $tempAreaCollIds;
            }
            
            return $return;
        }
    
        /**
         * 订单支付成功后的通知
         * author liuxiaodong
         * date 2020/1/2 16:53
         */
        public function payed()
        {
            try {
                ignore_user_abort( true );
    
                if( !APP_DEBUG && $this->_header['HTTP_X_SHOPIFY_TEST'] === 'true' ) {
                    $this->_setLog( '正式服务器上收到了测试的shopify信息,程序停止!请检查! HTTP_X_SHOPIFY_TEST = ' . $this->_header['HTTP_X_SHOPIFY_TEST'], Log::ERR );
                }
    
                if( $this->_paramArr['financial_status'] != 'paid' ) {
                    $this->_setLog( '订单状态异常,非paid !!' . $this->_paramArr['financial_status'] );
                    //流量商品需配置该信息,其他的商品,mos忽略
                    exit;
                }
    
                $imeis  = $cards = $all = [];
    //            if( empty( $this->_paramArr['note_attributes'] ) ){
    //                $this->_setLog( '未收到 note_attributes 信息,没有需要同步的信息' . json_encode( $this->_paramArr['note_attributes'] ) );
    //                //流量商品需配置该信息,其他的商品,mos忽略
    //                exit;
    //            }
                $productsDeivce     = [];
                foreach ( $this->_paramArr['line_items'] as $line_item) {
                    if( isset( $line_item['properties'] ) ) {
                        foreach( $line_item['properties'] as $prod ) {
                            $prod['type']   = $prod['name'];
                            $prod['name']   = "imei{$line_item['product_id']}";
                            $productsDeivce[]   = $prod;
                        }
                    }
                }
    
                if( empty( $productsDeivce ) ){
                    $this->_setLog( '未收到 productsDeivce 信息,没有需要同步的信息' . json_encode( $productsDeivce ) );
                    //流量商品需配置该信息,其他的商品,mos忽略
                    exit;
                }
                $this->_setLog( ' productsDeivce === ' . json_encode( $productsDeivce ) );
    
                if( $this->_paramArr['fulfillment_status'] == 'fulfilled' ) {
                    $this->_setLog( '该商品已发货' . json_encode( $this->_paramArr['fulfillment_status'] ) );
                    //流量商品需配置该信息,其他的商品,mos忽略
                    exit;
                }
    
                $redis  = getRedis();
                $rekey  = "ShopifyNotice:payed" . $this->_paramArr['token'];
                $ret    = $redis->setnx( $rekey, 1 );
                if( !$ret ) {
                    $this->_setLog( '该token已被处理,忽略' . json_encode( $this->_paramArr['token'] ) );
                    //token校验
                    exit;
                }
    
                $redis->expire( $rekey, 30 * 86400 );
                $skus   = [];
                $is_esim    = 0;
                $_esim_num  = '';
                foreach ( $productsDeivce as $item ) {
                    $productId  = trim( $item['name'], 'imei' );
                    $valInfo    = [];
    
                    foreach( $this->_paramArr['line_items'] as $prod ) {
                        if( $prod['product_id'] == $productId ) {
                            $valInfo    = [
                                'name'  => $prod['name'],
                                'sku'   => $prod['sku'],
                                'quantity'  => $prod['quantity'],
                                'id'    => $prod['id']
                            ];
                            $skus[]     = $prod['sku'];
                            break;
                        }
                    }
    
                    if( $item['type'] == 'esim' ) {
                        $is_esim    = 1;
                        for( $_i = 0; $_i < $valInfo['quantity']; $_i++ ) {
                            if( !isset( $all[$_esim_num] ) )
                                $all[$_esim_num]    = [$valInfo];
                            else
                                $all[$_esim_num][]    = $valInfo;  
                        }
                    }else {
                        //simcard ,macaroon 使用 imei
                        if( strlen( $item['value'] ) == 20 )
                            $cards[]  = $item['value'];
                        else
                            $imeis[]  = $item['value'];
    
                        if( !isset( $all[$item['value']] ) )
                            $all[$item['value']]    = [$valInfo];
                        else
                            $all[$item['value']][]    = $valInfo;
                    }
                }
    
                $this->_setLog( "设备商品信息:imeis==  " . json_encode( $imeis ) . " ;; cards ==  " . json_encode( $cards ) . " ;; is_esim == " . $is_esim );
    
                if( $is_esim ) {
                    $this->_setLog( 'esmi 类型;开始处理,无需检查设备信息 。。 valInfo == ' . json_encode($valInfo) );
                    
                }else {
                    if( empty( $imeis ) && empty( $cards ) ) {
                        $ret    = $this->_addNoteToOrder( $this->_paramArr['id'], 'MOS ERROR: 无设备,无卡,失败' );
                        if( $ret )
                            $this->_setLog( '发送shopify请求成功,ret' . $ret );
    
                        $this->_setLog( '无设备,无卡,请检查', Log::ERR );
                    }
    
                }
    
    
                //验证设备信息
                if( $imeis ) {
                    if( !$this->_checkImeis( $imeis ) ) {
                        $ret    = $this->_addNoteToOrder( $this->_paramArr['id'], 'MOS ERROR: 未找到有关的设备信息,失败' );
                        if( $ret )
                            $this->_setLog( '发送shopify请求成功,ret' . var_export($ret, true ) );
    
                        $this->_setLog( '服务器检查imei失败,请查看并更新错误!', Log::ERR );
                    }
                }
    
                if( $cards ) {
                    if( !$this->_checkCards( $cards ) ) {
                        $ret    = $this->_addNoteToOrder( $this->_paramArr['id'], 'MOS ERROR: 未找到有关的卡信息,失败' );
                        if( $ret )
                            $this->_setLog( '发送shopify请求成功,ret' .  var_export($ret, true ) );
    
                        $this->_setLog( '服务器检查imei失败,请查看并更新错误!', Log::ERR );
                    }
                }
                $this->_setLog( '验证设备信息成功,开始验证商品...' );
    
                //获取商品信息
                $newSkuInfo     = [];
                if( $skus ) {
                    $skuInfo    = $this->_checkSkus( $skus );
                    if( !$skuInfo ) {
                        $ret = $this->_addNoteToOrder($this->_paramArr['id'], 'MOS ERROR: 未找到有关的商品信息,失败');
                        if ($ret)
                            $this->_setLog('发送shopify请求成功,ret' .  var_export($ret, true ));
    
                        $this->_setLog( '服务器检查套餐失败,请查看并更新错误!skus = ' . var_export($skus, true ), Log::ERR );
                    }
                    foreach( $skuInfo as $item ) {
                        if( !isset( $item['validay'] ) ){
                            $item['validay']    = $item['validity'];
                        }
                        $newSkuInfo[$item['sku']]   = $item;
                    }
                    unset( $skuInfo );
                }else {
                    $ret    = $this->_addNoteToOrder( $this->_paramArr['id'], 'MOS ERROR: 商品没有配置SKU,失败' );
                    if( $ret )
                        $this->_setLog( '发送shopify请求成功,ret' .  var_export($ret, true ) );
    
                    $this->_setLog( '商品没有配置SKU信息,请检查', Log::ERR );
                }
                $this->_setLog( '验证商品信息成功,开始同步...' );
    
    
                $startTime      = new DateTime();
                $leaseLogic     = new LeaseLogic();
                //开始同步
                if( $all ) {
                    $oid            = createOrderNumber('SY');
                    $orderData      = $sonOrderData = [];
                    foreach( $all as $imei => $item ) {
    
                        foreach( $item as $ik => $iv ) {
                            $ginfo      = $newSkuInfo[$iv['sku']];
    
                            $orderData['gnames'][]  = $iv['name'];
                            $orderData['gshows'][$iv['id']]  = [
                                //data
                            ];
    
                            $endTmfd    = clone $startTime;
                            $addDays    = $iv['quantity'] * $ginfo['validity'];
                            $endTmfd->add( new DateInterval( "P{$addDays}D" ) );
                            $sonOrderData[]    = [//data]
                                
                        }
    
                    }
    
                    $gtid   = !empty( $imeis) ? GoodsModel::GTFLOW : GoodsModel::GTSIMFLOW;
                    if( $is_esim ) {
                        $gtid   = GoodsModel::GTESIMFLOW;
                    }
                    $addData        = [
                        //data
                    ];
    
                    $orderModel         = new PartnerGoodsOrderLogic();
                    $sonOrderModel      = new PartnerGoodsSonorderLogic();
                    $orderModel->startTrans();
                    if( !$orderModel->add( $addData ) ) {
                        $orderModel->rollback();
                        $this->_setLog( '服务器新增主订单失败' . json_encode( $addData ), Log::ERR );
                    }
    
                    if( !$sonOrderModel->addAll( $sonOrderData ) ) {
                        $orderModel->rollback();
                        $this->_setLog( '服务器新增子订单失败' . json_encode( $orderData ), Log::ERR );
                    }
                    $orderModel->commit();
                    $this->_setLog( '商品入库成功...' );
                    $ret    = $leaseLogic->_syncTsNew( $oid, [], 0, DataPackageModel::SOURCESHOPIFY );
                    $str    = $ret ? '成功' : '失败';
                    $node   = "MOS已同步[$oid]。结果: {$str}";
    
                    if( !$ret ) {
                        $this->_addNoteToOrder( $this->_paramArr['id'], $node );
                        $this->_setLog( 'MOS 同步失败,不发货...' );
                        $this->_setLog( '执行完毕...' );
                        return true;
                    }
                    $this->_setLog( '开始发货...' );
    
                    $esimList   = [];
                    if( $is_esim ) {
                        //esim 卡需要获取卡的二维码信息
                        $esimList   = (new PartnerGoodsSonorderLogic())->getEsimCardQcode( $oid );
                        if( !$esimList ) {
                            $this->_setLog( '开始发货...,esim 类型,获取二维码失败,发货失败' );
                            $this->_addNoteToOrder( $this->_paramArr['id'], $node . ' ;; 二维码读取失败,发货失败' );
                            return false;
                        }
                    }
    
                    $flag   = true;
                    foreach( $this->_paramArr['line_items'] as $item ) {
                        if( !$this->_fulfillment( $this->_paramArr['id'], $item['id'], $item['variant_id'], $node, $item['sku'], $esimList ) )
                            $flag   = false;
                    }
    
                    if( $flag )
                        $this->_setLog( '发货成功...' );
                    else
                        $this->_setLog( '发货失败...' );
    
                    $this->_setLog( '开始写note...' );
                    $this->_addNoteToOrder( $this->_paramArr['id'], $node );
                    $this->_setLog( '执行完毕...' );
                }
            }catch ( Exception $e ) {
                $this->_setLog( '执行过程出异常了...' . $e, Log::ERR );
            }
    
        }
    
        private function _esimJob( $valInfo, $skus )
        {
            $this->_setLog( '开始esmi发货处理....' . json_encode( ['valInfo' => $valInfo, 'skus' => $skus ] ) );
    
    
        }
    
        //商品创建
        public function prodUpdate()
        {
            if( !isset( $this->_paramArr['variants'] ) ) {
                $this->_setLog( '商品没有variants信息,忽略', Log::ERR );
            }
    
            $skus   = [];
            foreach( $this->_paramArr['variants'] as $item ) {
                $skus[]     = $item['sku'];
            }
            $md5Sku     = md5( json_encode( $skus ) . $this->_param['tags'] );
    
    
            $redis  = getRedis();
            $proSt  = $redis->hGet( $this->_productStatus, $this->_paramArr['id'] );
    
            if( $this->_paramArr['published_at'] ) {
                if( $proSt == $md5Sku ) {
                    $this->_setLog( '商品sku未更新,商品状态未更新,忽略', Log::WARN );
                    return;
                }else {
                    $this->_setLog( '开始下架原商品。。。' );
                    $this->prodDeletion( $this->_paramArr['id'] );
                    $this->_setLog( '下架完成。。。' );
                }
            }else {
                //下架
                $this->_setLog( '开始下架商品。。。' );
                $this->prodDeletion( $this->_paramArr['id'] );
                return;
            }
    
            //获取商品信息
            $model  = new GoodsLogic();
            $glist  = $model->getListSku( $skus, $this->_getPartners() );
            if( !$glist ) {
                $this->_setLog( '未获取到sku对应的信息,忽略该商品', Log::ERR );
            }
    
            $this->_setLog( "读取sku成功。" );
    
            $customCollect  = $this->_getCustomCollections();
    
            $collect    = $customCollectMof = [];
            $productArea  = [];
            foreach( $glist as $ginfo ) {
                if( empty( $ginfo['_area'] ) ) {
                    $this->_setLog( "改sku{$ginfo['sku']}没有对应的区域信息,忽略。" );
                    continue;
                }
    
                foreach( $ginfo['_area'] as $cityId ) {
                    $sim    = $dev  = $simOta = $simOnce = $esim = 0;
                    $_self_gtype    = null;
                    if( $ginfo['gtid'] == GoodsModel::GTFLOW ) {
                        $dev = 1;
                        $_self_gtype    = self::HANDLEDEVICE;
                    }else if( $ginfo['gtid'] == GoodsModel::GTSIMFLOW ) {
                        if( strpos( $this->_paramArr['tags'], self::TAGOTA ) !== false ) {
                            $simOta     = 1;
                            $_self_gtype    = self::HANDLEOTA;
                        }else if( strpos( $this->_paramArr['tags'], self::TAGONCE ) !== false ) {
                            $simOnce    = 1;
                            $_self_gtype    = self::HANDLEONCE;
                        }else {
                            $sim    = 1;
                            $_self_gtype    = self::HANDLESIM;
                        }
                    }else if( $ginfo['gtid'] == GoodsModel::GTESIMFLOW ) {
                        $esim   = 1;
                        $_self_gtype    = self::HANDLE_ESIM;
                    }
    
                    $this->_setLog( "处理城市id== {$cityId}; sim = {$sim}; dev = {$dev}; simota = {$simOta}; simonce = {$simOnce}; esim = {$esim}; _self_gtype == {$_self_gtype}" );
    
                    if( isset( $customCollect[$cityId] ) ) {
                        $_customCollectArr      = json_decode( $customCollect[$cityId], true );
                        $_customCollectId       = $_customCollectArr['id'];
                        $_customCollectHandle   = explode('_', $_customCollectArr['handle'] );
                        $_customCollectHandle[self::HANDLESIM]      = ( (int)$_customCollectHandle[self::HANDLESIM] ) + $sim;
                        $_customCollectHandle[self::HANDLEDEVICE]   = ( (int)$_customCollectHandle[self::HANDLEDEVICE] )  + $dev;
                        $_customCollectHandle[self::HANDLEOTA]      = ( (int)$_customCollectHandle[self::HANDLEOTA] )  + $simOta;
                        $_customCollectHandle[self::HANDLEONCE]     = ( (int)$_customCollectHandle[self::HANDLEONCE] )  + $simOnce;
                        $_customCollectHandle[self::HANDLE_ESIM]     = isset( $_customCollectHandle[self::HANDLE_ESIM] ) ? ( (int)$_customCollectHandle[self::HANDLE_ESIM] )  + $esim : $esim;
    
                        $collect[]  = [
                            'collect'   => [
                                'product_id'    => $this->_paramArr['id'],
                                'collection_id'     => $_customCollectId
                            ]
                        ];
                        $customCollectMof[$_customCollectId]     = [
                            'custom_collection'     => [
                                'id'        => $_customCollectId,
                                'handle'    => implode( '_', $_customCollectHandle )
                            ]
                        ];
    
                        $productArea[]  = $cityId;
    //                    $customCollectRedis[$cityId]   = json_encode( [ 'id' => $_customCollectId, 'handle' => implode( '_', $_customCollectHandle ) ] );
                    }else {
                        $collection     = $this->_createCollection( $cityId, $sim, $dev );
                        if( isset( $collection['id'] ) ){
                            $collect[]  = [
                                'collect'   => [
                                    'product_id'    => $this->_paramArr['id'],
                                    'collection_id'     => $collection['id']
                                ]
                            ];
                            $productArea[]  = $cityId;
                        }else {
                            $this->_setLog( "城市{$cityId}请求createCollection 失败,建立商品关系失败", Log::WARN );
                            continue;
                        }
    
    //                    $customCollectRedis[$cityId]   = json_encode( [ 'id' => $collection['id'], 'handle' => $collection['handle'] ] );
                    }
                }
            }
    
            if( $collect ) {
                $this->_setLog( "开始请求 collect 信息" );
                $this->_createCollect( $collect );
            }
    
            if( $customCollectMof ) {
                $this->_setLog( "有需要更新的custom collection信息。" );
                $this->_mofCollection( $customCollectMof );
            }
    
            if( $productArea ) {
                $this->_setLog( "设定商品对应的国家id关系。" . json_encode( $productArea ) );
                $productArea    = array_unique( $productArea );
                $redis->hSet( $this->_productToArea, $this->_paramArr['id'], implode( ',', $productArea ) . ',' . $_self_gtype );
            }
    
            $productType    = '';
            switch ( $_self_gtype ) {
                case self::HANDLESIM:
                    $productType    = self::SIMFLOW;
                    break;
                case self::HANDLEONCE:
                    $productType    = self::SIMONCEFLOW;
                    break;
                case self::HANDLEOTA:
                    $productType    = self::SIMOTAFLOW;
                    break;
                case self::HANDLEDEVICE:
                    $productType    = self::DEVICEFLOW;
                    break;
                case self::HANDLE_ESIM:
                    $productType    = self::ESIM;
                    break;
            }
            $redis->rPush( $this->_shopifyCurlQueue, json_encode( [
                'className'     => self::class,
                'method'        => 'mofProductJob',
                'param'         => [
                    'product' => [
                        'id'    => $this->_paramArr['id'],
                        'product_type'  => $productType
                    ]
                ],
                'doTimes'       => 0
            ] ) );
    
            $redis->hSet( $this->_productStatus, $this->_paramArr['id'], $md5Sku );
            $this->_setLog( "执行完毕。ok" );
        }
    
        public function prodDeletion( $id = null )
        {
            if( !$id )
                $id     = $this->_paramArr['id'];
    
            if( !$id ) {
                $this->_setLog( "id 「{$id}」 为空。忽略。。" );
                return;
            }
    
            $redis  = getRedis();
    
            //清理管连关系
            $area   = $redis->hGet( $this->_productToArea, $id );
            if( !$area ) {
                $this->_setLog( "未找到商品的关联区域信息。忽略。。" );
                return;
            }
            $redis->hDel( $this->_productToArea, $id );
    
            $areaArr    = explode( ',', $area );
            $gtype      = array_pop( $areaArr );
    
            $this->_setLog( "处理区域与custom collection关系" );
            $customCollectMof   = [];
            foreach( $areaArr as $cityId ) {
                $customCollect  = $redis->hget( $this->_cityToCollectionRedisKey, $cityId );
                if( $customCollect ) {
                    $_tmp       = json_decode( $customCollect, true );
                    $_handle    = explode( '_', $_tmp['handle'] );
    
                    switch ( $gtype ) {
                        case self::HANDLESIM:
                            $_handle[self::HANDLESIM]    = ( (int)$_handle[self::HANDLESIM] ) - 1;
                            break;
                        case self::HANDLEONCE:
                            $_handle[self::HANDLEONCE]    = ( (int)$_handle[self::HANDLEONCE] ) - 1;
                            break;
                        case self::HANDLEOTA:
                            $_handle[self::HANDLEOTA]    = ( (int)$_handle[self::HANDLEOTA] ) - 1;
                            break;
                        case self::HANDLEDEVICE:
                            $_handle[self::HANDLEDEVICE]    = ( (int)$_handle[self::HANDLEDEVICE] ) - 1;
                            break;
                        case self::HANDLE_ESIM:
                            $_handle[self::HANDLE_ESIM]    = ( (int)$_handle[self::HANDLE_ESIM] ) - 1;
                            break;
                    }
                    $_tmp['handle']     = implode( '_', $_handle );
    
                    $customCollectMof[]     = [
                        'custom_collection'     => [
                            'id'        => $_tmp['id'],
                            'handle'    => $_tmp['handle']
                        ]
                    ];
    
                    $_tmp       = null;
                }
            }
    
            if( $customCollectMof )
                $this->_mofCollection( $customCollectMof );
    
            $redis->hSet( $this->_productStatus, $id, '' );
        }
    
        private function sendRequest( $method, $urlExtend, $data = '', $header = [], $needResHeader = false )
        {
            static $tryTimes = 1;
            $tmpHeader  = ['Content-Type:application/json','Cache-Controller: max-age=0', 'Authorization: Basic ' . $this->_api['authorization']];
            if( is_array( $data ) && !empty( $data ) ) {
                $data   = json_encode( $data );
                $tmpHeader[]   = 'Content-Length: ' . strlen( $data );
            }else {
                $data   = (string)$data;
            }
    
            if( !empty( $header ) ) {
                $tmpHeader  = array_merge( $tmpHeader, $header );
            }
    
            $redis  = getRedis();
    
            $url    = "https://{$this->_api['key']}:{$this->_api['pwd']}@{$this->_api['url']}{$this->_api['version']}/{$urlExtend}";
            $this->_setLog( '开始curl '. $method .' ,url == ' . $url . ',, param == ' . $data );
            $ret    = $this->_curl->execute( $method, $url, $data, '',  $tmpHeader, '', '', $needResHeader );
            if( is_array( $ret ) || $ret === false ) {
                $tryTimes++;
                if( $tryTimes >= 1 ) {
                    $this->_curlLastErr     = "send curl error ..";
                    if( isset( $ret[1] ) )
                        $this->_curlLastErr     .= "{$ret[1]}";
                    $this->_setLog( 'curl 请求shopify失败,请检查! ' . json_encode( $ret ), Log::WARN );
                    //添加到重试队列
                    $redis->rPush( $this->_shopifyCurlQueue, json_encode( [
                        'className'     => self::class,
                        'method'        => 'curlRedoJob',
                        'param'         => [
                            'method'    => $method,
                            'url'       => $urlExtend,
                            'data'      => $data,
                            'header'    => $header,
                            'needResHeader'     => $needResHeader
                        ],
                        'doTimes'       => 0
                    ] ) );
                    return false;
                }else {
                    return $this->sendRequest( $method, $urlExtend, $data, $header, $needResHeader );
                }
            }
    
            $deRet    = json_decode( $ret, true );
    
            if( $needResHeader ) {
                if( isset( $deRet['ret']['errors'] ) ) {
                    $this->_curlLastErr     = $ret;
                    $this->_setLog( '请求成功,但是返回了失败,.' . $ret, Log::WARN );
                    return false;
                }
            }else {
                if( isset( $deRet['errors'] )  || isset( $deRet['error'] ) ) {
                    $this->_curlLastErr     = $ret;
                    $this->_setLog( '请求成功,但是返回了失败,.' . $ret, Log::WARN );
                    return false;
                }
            }
    
            $this->_setLog( '请求成功了,' . $ret  );
    
            return $deRet;
        }
    
        public function curlRedoJob( $data )
        {
            $ret    = $this->sendRequest( $data['method'], $data['url'], $data['data'], $data['header'], $data['needResHeader'] );
            if( !$ret ) {
                return false;
            }
    
            return true;
        }
    
        //给订单添加note
        private function _addNoteToOrder( $oid, $note )
        {
            $param  = ['order' => [
                'id' => $oid,
                'note'  => $note
            ]];
            $ret    = $this->sendRequest( 'PUT', "orders/{$oid}.json", $param  );
            if( !$ret ) {
                $this->_setLog( '请求_addNoteToOrder失败了' . var_export( $ret, true ), Log::ERR );
            }
            return $ret;
        }
    
        private function _getCustomCollections( $force = false )
        {
            $ret    = [];
            $redis  = getRedis();
            $ret    = $redis->hGetAll( $this->_cityToCollectionRedisKey );
            if( $ret && !$force )
                return $ret;
    
            $url    = 'custom_collections.json?limit=250';
            while( true ) {
                $list   = $this->sendRequest( 'GET', $url, '', [] ,true );
                $retArr     = json_decode( $list['ret'], true );
                if( empty( $retArr['custom_collections'] ) ) {
                    $this->_setLog( '获取CustomCollections失败,请检查.' . var_export( $list, true ), Log::WARN );
                    return [];
                }
                foreach( $retArr['custom_collections']  as $item ) {
    //                $tmpPatten  = "/<inputstype="hidden"svalue='(.*?)'>/";
    //                $match      = [];
    //                if( !preg_match( $tmpPatten, $item['body_html'], $match ) ) {
    //                    continue;
    //                }
    
    //                $storeInfo  = json_decode( $match[1], true );
    //                $id         = $storeInfo['id'];
    //                if( !$id )
    //                    continue;
    
                    $_tmp       = explode( '_', $item['handle'] );
                    if( !isset( $_tmp[1] ) )
                        continue;
                    $id         = $_tmp[1];
                    $ret[$id]   = json_encode( [ 'id' => $item['id'], 'handle' => $item['handle'] ] );
                }
    
                $linkPattern    = "/link:s<(.*)>/U";
                $match      = [];
                if( preg_match( $linkPattern, $list['header'],$match ) ) {
                    $url    = "custom_collections.json?" . parse_url( $match[1] )['query'];
                }else {
                    break;
                }
            }
    
            $redis->hMset( $this->_cityToCollectionRedisKey, $ret );
            return $ret;
        }
    
        public function initCreateCollection()
        {
            $this->_createCollection( 'init' );
        }
    
        private function _createCollection( $ids = '', $sim = 0, $dev = 0, $ota = 0, $noOta = 0 )
        {
            $isLand     = [
                1   => 'America',
                2   => 'Oceania',
                4   => 'Africa',
                5   => 'Europe',
                6   => 'Asia'
            ];
    
            if( !$ids )
                return false;
    
            $where  = [];
            if( $ids ) {
                if( $ids === 'init' ) {
                    $where  = [];
                }else
                    $where['ids']   = $ids;
            }
    
            $country     = new CountryLogic();
            $list       = $country->getCountryList( $where );
            foreach( $list as $item ) {
                if( empty( $item['english_language'] ) ) {
                    $this->_setLog( '城市' . $item['id'] . '没有英文名称!!!', Log::WARN );
                    continue;
                }
    
                $continentName  = isset( $isLand[$item['continent_id']] ) ? $isLand[$item['continent_id']] : 'other';
                if( $continentName == 'other' ) {
                    echo $item['name'] . "<br />";
                }
    //            $json       = json_encode( [
    //                'id'    => $item['id'],
    //                'sim'   => $sim,
    //                'dev'   => $dev,
    //                'cn'    => $item['name'],
    //                'jp'    => $item['ja_name']
    //            ], JSON_UNESCAPED_UNICODE );
    
                $handle     = strtolower( $continentName ) . "_{$item['id']}_{$sim}_{$dev}_{$ota}_{$noOta}";
                $param  = [
                    'custom_collection'     => [
                        'title'     => strtolower( $item['english_language'] ),
                        'handle'    => $handle,
                    ]
                ];
    
                $ret    = $this->sendRequest( 'POST', 'custom_collections.json', $param );
                if( !$ret ) {
                    $this->_setLog( '城市' . $item['id'] . '建立custom_collections失败!!!', Log::WARN );
                    return false;
                }
    
                $redis  = getRedis();
                $redis->hSet( $this->_cityToCollectionRedisKey, $item['id'], json_encode( [ 'id' => $ret['custom_collection']['id'], 'handle' => $handle ] ) );
    
                if( $ids === 'init' )
                    continue;
                else
                    return $ret['custom_collection'];
            }
    
            return false;
        }
    
        private function _mofCollection( $data )
        {
            $redis  = getRedis();
            foreach( $data as $item ) {
    //            $ret    = $this->sendRequest( 'PUT',  'custom_collections/' . $item['custom_collection']['id'] . '.json', $item );
    //            if( !$ret ) {
    //                $this->_setLog( "更新custom collection 失败" . var_export( $item, true ) );
    //                continue;
    //            }
    
                $redis->rPush( $this->_shopifyCurlQueue, json_encode( [
                    'className'     => self::class,
                    'method'        => 'mofCollectionJob',
                    'param'         => $item,
                    'doTimes'       => 0
                ] ) );
    
                $handleArr  = explode( '_', $item['custom_collection']['handle'] );
                $redis->hSet( $this->_cityToCollectionRedisKey, $handleArr[1], json_encode( ['id' => $item['custom_collection']['id'] , 'handle' => $item['custom_collection']['handle'] ] ) );
            }
        }
    
        public function mofCollectionJob( $data )
        {
            $ret    = $this->sendRequest( 'PUT',  'custom_collections/' . $data['custom_collection']['id'] . '.json', $data );
            if( !$ret ) {
                return false;
            }
    
            return true;
        }
    
        public function mofProductJob( $data )
        {
            $ret    = $this->sendRequest( 'PUT',  "products/{$data['product']['id']}.json", $data );
            if( !$ret ) {
                return false;
            }
    
            return true;
        }
    
        private function _createCollect( $data )
        {
            $redis  = getRedis();
            foreach( $data as $item ) {
    
                $redis->rPush( $this->_shopifyCurlQueue, json_encode( [
                    'className'     => self::class,
                    'method'        => 'createCollectJob',
                    'param'         => $item,
                    'doTimes'       => 0
                ] ) );
    //            $ret    = $this->sendRequest( 'POST', 'collects.json', $item  );
    //            if( !$ret ) {
    //                $this->_setLog( "设定商品,collect 关联关系失败" . var_export( $ret, true ) );
    //                continue;
    //            }
    
    //            $reval  = $redis->hGet( $this->_productToCoolectRedisKey, $item['collect']['product_id'] );
    //            $setVal     = "{$ret['collect']['id']}";
    //            if( $reval )
    //                $setVal .= ",{$reval}";
    //            $redis->hSet( $this->_productToCoolectRedisKey, $item['collect']['product_id'], $setVal );
            }
        }
    
        public function createCollectJob( $data )
        {
            $ret    = $this->sendRequest( 'POST', 'collects.json', $data  );
            if( !$ret ) {
                if( strpos( $this->_curlLastErr, 'already exists' ) ) {
                    return true;
                }
                return false;
            }
    
            return true;
        }
    
        /**
        private function _delCollect( $productId )
        {
            $redis  = getRedis();
            $ret    = $redis->hGet( $this->_productToCoolectRedisKey, $productId );
            if( !$ret ) {
                $this->_setLog( "该商品无collect信息" );
                return;
            }
    
            $data   = explode( ',', $ret );
            foreach( $data as $item ) {
                $ret    = $this->sendRequest( 'DELETE', "collects/{$item}.json"  );
                if( $ret === false ) {
                    $this->_setLog( "设定商品,collect 清理关联关系失败" . var_export( $ret, true ) );
                    continue;
                }
            }
            $redis->hDel( $this->_productToCoolectRedisKey, $productId );
        }
        */
    
        //获取商品
        private function _fulfillment( $oid, $lineItemId, $variantRestId, &$note, $sku, $esimList = [] )
        {
            $ret    = $this->sendRequest( 'GET', "variants/{$variantRestId}.json" );
            if( !$ret ) {
                $note   .= "
     获取商品信息异常(variants),发货失败";
                $this->_setLog( "variants/{$variantRestId}.json 请求失败。" . var_export( $ret, true ) );
                return false;
            }
    
            $ret    = $this->sendRequest( 'GET', "inventory_levels.json?inventory_item_ids={$ret['variant']['inventory_item_id']}" );
            if( !$ret ) {
                $note   .= "
     获取商品信息异常(inventory_levels),发货失败";
                $this->_setLog( "inventory_levels.json?inventory_item_ids={$ret['variant']['inventory_item_id']} 请求失败。" . var_export( $ret, true ) );
                return false;
            }
    
            $param  = [
                'fulfillment'   => [
                    'location_id'   => $ret['inventory_levels'][0]['location_id'],
                    'tracking_number'   => null,
                    'line_items'    => [['id' => $lineItemId]]
                ]
            ];
            if( isset( $esimList[$sku] ) ) {
                $tracking_urls  = $esimList[$sku];
                $param['fulfillment']['tracking_numbers']  = $tracking_urls;
                
                foreach( $tracking_urls as &$_item ) {
                    $_item  = $this->createEsimQrImg( $_item );
                }
                unset( $_item );
                $param['fulfillment']['tracking_urls']  = $tracking_urls;
                $param['fulfillment']['tracking_company']  = 'self';
            }
    
            $ret    = $this->sendRequest( 'POST', "orders/{$oid}/fulfillments.json", $param );
            if( !$ret ) {
                $note   .= "
     请求发货接口失败,发货失败";
                $this->_setLog( "orders/{$oid}/fulfillments.json 请求失败。" . var_export( $ret, true ) );
                return false;
            }
            return true;
        }
    
        public function createEsimQrImg( $str )
        {
            $path = './' . C("UPLOADPATH") . 'qrcode/'; //上传主目录
            $file_name = $path . md5( $str ) . '.png';
            if (!file_exists($file_name)) {
                $QR = new CommonLibQrcode();
                $logo = "./public/images/esim_qr_logo.png";
                if (!file_exists($path)) {
                    mkdir($path, 755, true);
                }
                $bgImg = "./public/images/esim_qr_bg.png";
                $QR->create_with_background($str, $file_name, 'M', 10, $logo, $bgImg);
            }
            if (file_exists($file_name)) {
                $img = $file_name ? 'http://' . $_SERVER['SERVER_NAME'] . '/' . $file_name : '';
            }
            return $img;
        }
    
        public function __call($name, $arguments)
        {
            // TODO: Implement __call() method.
            $data   = [
                'name'  => $name,
                'arg'   => $arguments
            ];
            $this->_setLog( json_encode( $data ) );
            return true;
        }
    
        private function _checkImeis( $imeis )
        {
            $model  = new DeviceLogic();
            $count  = $model->getCountInImei( $this->_partner, $imeis );
            if( $count != count( array_unique( $imeis ) ) )
                return false;
    
            return true;
        }
    
        private function _checkCards( $cards )
        {
            $model  = new SimcardLogic();
            $count  = $model->getCountInImei( $this->_partner, $cards );
            if( $count != count( array_unique( $cards ) ) )
                return false;
    
            return true;
        }
    
        private function _checkSkus( $skus )
        {
            $model  = new GoodsLogic();
            $count  = $model->getListSku( $skus, $this->_partner );
            if( count( $count ) != count( array_unique( $skus ) ) )
                return false;
    
            return $count;
        }
    
        private function _getPartners()
        {
            $partner    = new PartnerLogic();
            $list       = $partner->getSonList( PartnerModel::UROAMING_PARTNER_ID );
            return array_keys( $list );
        }
    
        //验证来源
        private function _checkParam()
        {
            if( IS_CLI  ) {
                return true;
            }
    
            $hashStr    = base64_encode( hash_hmac( 'sha256', $this->_param, $this->_sign, true ) );
            if(  $this->_header['HTTP_X_SHOPIFY_HMAC_SHA256'] !== $hashStr ) {
                $this->_setLog( '服务器校验来源异常,程序停止!请检查!', Log::ERR );
                return false;
            }
            $this->_setLog( '检查参数合法性成功' );
            return true;
        }
    
        private function _setLog( $msg, $level = Log::NOTICE )
        {
            if( !$this->_logque instanceof SplQueue )
                $this->_logque  = new SplQueue();
    
            $this->_logque->enqueue( $msg . PHP_EOL );
    
            if( $level == Log::ERR ) {
                //send mail
                exit;
            }
        }
    
        public function __destruct()
        {
            if( $this->_logque instanceof SplQueue ) {
                $msg        = '';
                while( !$this->_logque->isEmpty() ) {
                    $msg    .= $this->_logque->dequeue();
                }
                Log::write( $msg, Log::NOTICE, '', durableLog( 'api-shopify' ) );
            }
        }
    
        public function test()
        {
            $model  = new SimcardLogic();
            var_dump( $model->getEsimEmpty( 2, [1])); 
        }
    }
  • 相关阅读:
    [手游项目2]-25-linux 端口time_wait
    [手游项目2]-24-linux MySql编译安装
    诛仙手游法宝铸元性价比
    法宝精进性价比对比
    [手游项目2]-23-游戏数据存储解决方案
    [手游项目2]-22-lua内存问题
    [手游项目2]-21-死循环排查
    [手游项目2]-20-mysql还原一个库的部分数据
    [手游项目2]-19-EError=1118, Reason=Row size too large (> 8126)
    bzoj1471
  • 原文地址:https://www.cnblogs.com/lxdd/p/13937660.html
Copyright © 2011-2022 走看看