<?php

namespace Business\Store;

/**
 * 店铺service
 *
 * @date 2018-5-15
 * @author zhz
 */
class StoreServiceModel extends \Business\AbstractModel{


    public function init() {
    }

//    public function get($storeId,$label = true){
//        $storeInstance = \DAO\StoreModel::getInstance();
//        $storeInfo = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(),array(&$storeInstance, 'getInfoById'),array($storeId));
//        if(!$storeInfo){
//            \Error\ErrorModel::throwException(\Error\CodeConfigModel::storeNotExistOrClose);
//        }
//
//        if($label){
//            //店铺头像
//            $storeLabel = $storeInstance->getStoreLabelSrc($storeInfo['store_label']);
//
//            return array($storeInfo,$storeLabel);
//        }
//        return $storeInfo;
//    }

    /**
     * 获取店铺首页渲染信息
     * add by zhz
     *
     * @param $store_id
     * @param $memberId
     */
    public function getStoreInfo($param,$memberId,$address){
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        if($address) {
            $lng = $address['lng'];
            $lat = $address['lat'];
        }else{
            $lng = $param['lng'];
            $lat = $param['lat'];
        }
        if(!$lng || !$lat){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyLatLngParam);
        }
        list($storeInfo,$storeLabel) = \DAO\StoreModel::getInstance()->get($storeId);
        if((int)$param['isScan'] > 0) {
            //扫码进入
            if($memberId > 0) {
                if($param['sid']) {
                    $sale = \DAO\SaleModel::getInstance()->getOne(array('sale_id'=>$param['sid']),'sale_act_id,member_id');
                    if($sale) {
                        \DAO\SaleMemberModel::getInstance()->insertOrUpdate(array('sale_id'=>$sale['member_id'],'sale_act_id'=>$sale['sale_act_id'],'member_id'=>$memberId,'store_id'=>$storeId));
                    }
                }
//                $storeMember['storeId'] = $storeId;
//                $storeMember['memberId'] = $memberId;
//                $storeMember['type']    = \Our\ApiConst::storeQrcodeMember;
//                $storeMembers[] = $storeMember;
//                $storeMemberDao = \DAO\StoreMemberModel::getInstance(\Our\DbNameConst::masterDBConnectName);
//                $result = $storeMemberDao->addBatch($storeMembers);
            }else{
                $sess=\Yaf\Session::getInstance();
                $scan_store_ids = $sess->get('scan_store_ids');
                is_array($scan_store_ids) ? $scan_store_ids = $scan_store_ids : $scan_store_ids = [];
                array_push($scan_store_ids,$storeId);
                $sess['scan_store_ids'] = array_unique($scan_store_ids);
                if($param['sid']) {
                    $scan_sale_ids = $sess->get('scan_sale_ids');
                    is_array($scan_sale_ids) ? $scan_sale_ids = $scan_sale_ids : $scan_sale_ids = [];
                    $sid = (int)$param['sid'];
                    $scan_sale_ids[$sid] = $storeId;
                    //array_push($scan_sale_ids,$sid);
                    //$scan_sale_ids[$sid.','.$aid] = array($sid=>$storeId);
                    $sess['scan_sale_ids'] = $scan_sale_ids;
                }
            }
        }
        $adv['imageUrl'] = \DAO\StoreModel::getInstance()->getStoreBanner($storeInfo['store_index_banner']);
        $adv['href'] = '';
        //评分
        $storeScoreDAO = \DAO\StoreScoreStatisticsModel::getInstance();
        $storeScore = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreScoreStatisticsRedisModel::getInstance(), array(&$storeScoreDAO, 'getOne'), array('*',array('store_id'=>$storeId)),\Our\ApiConst::oneDaySecond);
        if($storeScore === false){
            $storeScore['evaluation_score'] = 0;
            $storeScore['evaluation_number'] = 0;
        }
        $storeScore['evaluation_score'] ? $grade = number_format(($storeScore['evaluation_score']/3/$storeScore['evaluation_number']),1,'.',''):$grade = '5.0';

        //月销量
        $storeMonthInstance = \DAO\StoreMonthSalesModel::getInstance();
        $monthlySalesCount = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(),array(&$storeMonthInstance, 'getStoreMonthSales'),array($storeId),\Our\ApiConst::oneDaySecond);
        $monthlySalesCount = $monthlySalesCount ? $monthlySalesCount : 0;

        //位置相关
        $distince = \Our\CommonExtension::getDistance($lat,$lng,$storeInfo['store_latitude'],$storeInfo['store_longitude']);
        $defaultDeliveryTime = 0;

        if($distince>0){
            if(!empty($storeInfo['store_sales_scope'])){
                $str = str_replace('\"','"',$storeInfo['store_sales_scope']);
                $store_sales_scope = json_decode($str,true);
                if(is_array($store_sales_scope)&&count($store_sales_scope)>0){
                    //\Our\ValidationMap::setCoordArray($store_sales_scope);
                    $location = array('lat'=>$lat,'lng'=>$lng);
                    //$in_store_service_flag = \Our\ValidationMap::isCityCenter($location);
                    $in_store_service_flag = \Our\CommonExtension::isPointInPolygon($store_sales_scope,$location);
                    if($in_store_service_flag){
                        $in_store_service_flag=1;
                        $DeliveryFormulaInstance = \DAO\DeliveryFormulaModel::getInstance();
                        $deliveryFormula = \Our\RedisHelper::cachedFunction(\Redis\Db6\DeliveryFormulaRedisModel::getInstance(),array(&$DeliveryFormulaInstance, 'getOne'),array('*',array('store_id'=>$storeId)),\Our\ApiConst::sevenDaySecond,array($storeId));
                        $formula = $DeliveryFormulaInstance->getDeliveryFormulaByDistince($storeId,$distince,$deliveryFormula);
                        //如果采用精简版公式，获取常速送达的时间作为默认送达时间
                        if($formula){
                            $defaultDeliveryTime = (empty($formula['default_time'])?$formula[2]['time']:$formula['default_time']);
                        }
                        if(!$defaultDeliveryTime){
                            //$in_store_service_flag = 0;
                            $defaultDeliveryTime = 0;
                        }
                    }else{
                        $in_store_service_flag=0;
                        $defaultDeliveryTime = 0;
                    }
                }
            }
        }
        //关注
        $favType = 0;
        if($memberId){
            $FavoritesStoreInstance = \DAO\FavoritesStoreModel::getInstance();
            $favInfo = \Our\RedisHelper::cachedFunction(\Redis\Db6\FavoritesStoreRedisModel::getInstance(),array(&$FavoritesStoreInstance, 'getOne'),array('*',array('store_id'=>$storeId,'member_id'=>$memberId)),\Our\ApiConst::oneDaySecond,array($memberId));
            if($favInfo && ($favInfo['fav_type'] == 1)){
                $favType = 1;
            }
        }
        return array('storeLabel'=>$storeLabel,'storeName'=>$storeInfo['store_name'],'grade'=>$grade,'fansCount'=>\DAO\FavoritesStoreModel::getInstance()->getFavoritesStoreCountByStoreId($storeId),'favType'=>$favType,'monthlySalesCount'=>$monthlySalesCount,'defaultDeliveryTime'=>$defaultDeliveryTime,'freeShippingPrice'=>$storeInfo['free_shipping_price'],'storeDistance'=>$distince,'storeNotice'=>$storeInfo['store_notice'],'startShippingPrice'=>$storeInfo['start_shipping_price'],'memberId'=>$storeInfo['member_id'],'inStoreService'=>$in_store_service_flag,'adv'=>$adv,'memberId'=>$storeInfo['member_id']);
    }

    /**
     * 获取店铺其他信息
     * @param $param
     * @return array
     * @throws \Our\Exception
     */
    public function getStoreDetail($param){
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }

        list($storeInfo,$storeLabel) = \DAO\StoreModel::getInstance()->get($storeId);
        //资质图片
        $detailImg = [];
        if($storeInfo['store_detail_image']){
            $storeDetailImg = unserialize($storeInfo['store_detail_image']);
            if($storeDetailImg && is_array($storeDetailImg)){
                foreach ($storeDetailImg as $v){
                    $detailImg[] = \DAO\StoreModel::getInstance()->getStoreLabelSrc($v, \Our\ImageConst::storeQualificationImg);
                }
            }
        }
        //地址
        $address = '';
        if($storeInfo['area_info']){
            $address .= $storeInfo['area_info'];
        }
        if($storeInfo['store_address']){
            $address .= $storeInfo['store_address'];
        }
        //营业时间
        $openingHours = '';
        if($storeInfo['store_start_time'] && $storeInfo['store_close_time']){
            $openingHours = $storeInfo['store_start_time'].'-'.$storeInfo['store_close_time'];
        }
        //店铺经营分类
        $goodsClassInstance = \DAO\GoodsClassModel::getInstance();

        $class = \Our\RedisHelper::cachedFunction(\Redis\Db6\GoodsClassRedisModel::getInstance(),array(&$goodsClassInstance, 'getStoreClass'),array($storeId),\Our\ApiConst::oneDaySecond,array($storeId));

        $returnClass = [];
        if($class){
            foreach ($class as $v){
                $returnClass[] = $v['gc_name'];
            }
        }
        return array('storeName'=>$storeInfo['store_name'],'storeLabel'=>$storeLabel,'fansCount'=>\DAO\FavoritesStoreModel::getInstance()->getFavoritesStoreCountByStoreId($storeId),'clazz'=>$returnClass,'address'=>$address,'storePhone'=>$storeInfo['store_phone'],'openingHours'=>$openingHours,'storeService'=>$storeInfo['store_notice'],"qualificationImage"=>$detailImg);
    }
    public function getRecommendGoodsCache($param,$memberId){
        $recommendGoods = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreGoodsClassRedisModel::getInstance(),array(&$this, 'getRecommendGoods'),array($param,$memberId),\Our\ApiConst::oneDaySecond,array(intval($param['storeId'])));
        return $recommendGoods;
    }
    /**
     * 获取店铺首页推荐商品
     * @param $param
     */
    public function getRecommendGoods($param,$memberId){
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        \DAO\StoreModel::getInstance()->get($storeId,false);

        $activities = \DAO\SaleMemberModel::getInstance()->isJoinStore($storeId,$memberId);

        $storeClassDAO = \DAO\StoreGoodsClassModel::getInstance();
        $tempStcs = $storeClassDAO->getList(array('store_id'=>$storeId),'stc_id,stc_name');
        if($tempStcs) {
            $storeClassGoodsDao = \DAO\StoreGoodsClassGoodsModel::getInstance();
            $stcGoods = $storeClassGoodsDao->getList('stc_id in('.implode(',',array_column($tempStcs,'stc_id')).')','stc_id,goods_common_id');
        }
        $recommendGoods = [];
        if($stcGoods){
            $goodsIds = array_column($stcGoods,'goods_common_id');
            $goodsCommonDAO = \DAO\GoodsCommonModel::getInstance();
            if($activities === false){
                $tempGoods = $goodsCommonDAO->getGoodsList(array('goods_commonid in('.implode(',',$goodsIds).')'),'goods_name,goods_image,goods_price,goods_marketprice,goods_commonid');
            }else{
                $activities = array_keys($activities);
                $tempGoods = $goodsCommonDAO->getListWithSale(array('han_goods_common.goods_commonid in('.implode(',',$goodsIds).')'),'goods_name,goods_image,goods_price,goods_marketprice,han_goods_common.goods_commonid',$activities);
            }
            if($tempGoods && $tempStcs){
                $stcs = [];
                foreach ($tempStcs as $v){
                    $stcs[$v['stc_id']] = $v;
                }
                $goods = [];
                foreach ($tempGoods as $v){
                    $goods[$v['goods_commonid']] = $v;
                }
                foreach ($stcGoods as $v){
                    if(isset($goods[$v['goods_common_id']])){
                        $good = [
                            'goodsCommonId'=>$v['goods_common_id'],
                            'goodsName'=>$goods[$v['goods_common_id']]['goods_name'],
                            'goodsImage'=>\Our\ImageUtil::getGoodsImgUrl($goods[$v['goods_common_id']]['goods_image']),
                            'goodsPrice'=>$goods[$v['goods_common_id']]['goods_price'],
                            'goodsMarketPrice'=>$goods[$v['goods_common_id']]['goods_marketprice'],
                        ];
                        if(key_exists($v['stc_id'],$recommendGoods)){
                            if(count($recommendGoods[$v['stc_id']]['goods']) >= 8){
                                continue;
                            }
                            array_push($recommendGoods[$v['stc_id']]['goods'],$good);
                        }else{
                            $recommendGoods[$v['stc_id']] = [
                                'stcId'=>$v['stc_id'],
                                'stcName'=>$stcs[$v['stc_id']]['stc_name'],
                                'goods'=>array($good)
                            ];
                        }
                    }
                }
                $recommendGoods = array_values($recommendGoods);
            }
        }
//        var_dump($recommendGoods);
//        var_dump($stcGoods);
//        var_dump($stcs);exit;
//        if($activities === false){
//            $field = 'han_store_goods_class.stc_id,han_store_goods_class.stc_name,han_goods_common.goods_commonid,han_goods_common.goods_name,han_goods_common.goods_image,han_goods_common.goods_price AS price,han_goods_common.goods_marketprice';
//            $where = 'han_store_goods_class.store_id = '.$storeId;
//            $recommendGoods = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreGoodsClassRedisModel::getInstance(),array(&$StoreGoodsDAO, 'getList'),array($where,$field),\Our\ApiConst::oneDaySecond,array($storeId));
//        }else{
//            $field = 'han_store_goods_class.stc_id,han_store_goods_class.stc_name,han_goods_common.goods_commonid,han_goods_common.goods_name,han_goods_common.goods_image,han_goods_common.goods_price,IFNULL(discount_price,han_goods_common.goods_price) AS price,han_goods_common.goods_marketprice';
//            $where = 'han_store_goods_class.store_id = '.$storeId;
//            //$data = $StoreGoodsDAO->getListWithSale($where,$field,$activities);
//            $recommendGoods = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreGoodsClassRedisModel::getInstance(),array(&$StoreGoodsDAO, 'getListWithSale'),array($where,$field,$activities),\Our\ApiConst::oneDaySecond,array($storeId));
//        }
        return $recommendGoods;
    }
    /**
     * 获取举报选项
     * @return array
     * @throws \Our\Exception
     */
    public function getReason(){
        $reportRestoreInstance = \DAO\ReportRestoreModel::getInstance();
        $reason = \Our\RedisHelper::cachedFunction(\Redis\Db6\ReportRestoreRedisModel::getInstance(),array(&$reportRestoreInstance, 'getList'),array(),\Our\ApiConst::sevenDaySecond);
        $reason || $reason = [];
        return array('reasons'=>$reason);
    }

    /**
     *
     * 举报商家
     * @param $param
     * @param $memberId
     */
    public function report($param,$memberId){
        $storeId = (int)($param['storeId']);
        $describe = $param['describe'];
        $resonId = (int)($param['reasonId']);
        $type = (int)$param['type'];
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        if(!$resonId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyReportStoreType);
        }
        if(!$describe){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyReportStoreDesc);
        }
        if(!$memberId){
            return false;
        }
        \DAO\StoreModel::getInstance(\Our\DbNameConst::masterDBConnectName)->get($storeId,false);

        $imgArr = array();
        for ($i = 0 ; $i < 2 ; $i++){
            $number = str_replace(array(0,1,2),array('A','B','C'),$i);
            $image = $param['image'.$number];
            if($image && $type == 0){
                $time = date('YmdHis_');
                $file_name = $time.\Our\Validate::getNumberString();
                $result = \Our\ImageUtil::uploadBase64Image($image,\Our\ImageConst::reportShops,$file_name);
                if($result){
                    $imgArr[] = $file_name;
                }
            }else{
                $imgArr[] = pathinfo($image)['basename'];
            }
        }
        $insert = array();
        $insert['report_image'] = serialize($imgArr);
        $insert['report_describe'] = $describe;
        $insert['report_time'] = time();
        $insert['restore_id'] = $resonId;
        $insert['member_id'] = $memberId;
        $insert['seller_id'] = $storeId;

        $return = \DAO\ReportModel::getInstance()->insert($insert);
        if(!$return){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::saveReportError);
        }
    }


    /**
     * 关注
     * @param $param
     * @param $memberId
     * @return bool|string
     * @throws \Our\Exception
     */
    public function collect($param,$memberId){
        if(!$memberId){
            return false;
        }
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        $storeInfo = \DAO\StoreModel::getInstance()->get($storeId,false);

        if($storeInfo['member_id'] == $memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::illegalFavStore);
        }

        $FavoritesStoreInstance = \DAO\FavoritesStoreModel::getInstance();
        $return = $FavoritesStoreInstance->insertOrUpdate(array('member_id'=>$memberId,'store_id'=>$storeId,'fav_time'=>time()));

        if((int)$return > 0){
            //更新店铺收藏数
            $FavoritesStoreInstance->getFavoritesStoreCountByStoreId($storeId, 1);
            //删除缓存
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\FavoritesStoreRedisModel::getInstance(),array(&$FavoritesStoreInstance, 'getOne'),array('*',array('store_id'=>$storeId,'member_id'=>$memberId)),array($memberId));
            \Our\RedisHelper::delCachedFunction(\Redis\Db6\FavoritesStoreRedisModel::getInstance(),array(&$FavoritesStoreInstance, 'getList'),array(),array($memberId));
            //更新个人中心首页数量
            \DAO\MemberModel::getInstance()->_changeNum(\Our\NameConst::storeCollection,$memberId);
            return true;
        }
    }

    /**
     * 获取搜索页推荐关键字
     * @param $param
     */
    public function getKeywords($param){
        $storeId = $param['storeId'];
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        $storeInfo = \DAO\StoreModel::getInstance()->get($param['storeId'],false);

        $recommendWord = unserialize($storeInfo['recommend_word']);
        $recommendWord ? $recommendWord : $recommendWord=[];
        return array('recommendWord'=>$recommendWord);
    }

    /**
     * 获取附近的店铺
     * @param $data
     */
    public function getNearbyStores($where){
        $addressDao = \DAO\AddressModel::getInstance();
        $validFlag = $addressDao->getValidAddress($where);
        if(!$validFlag){
            \Error\ErrorModel::throwException($addressDao->errorCode);
        }
        $position['lat'] = $where['lat'];
        $position['lng'] = $where['lng'];
        $position['cityCode'] = $where['cityCode'];
        $readisSuffix = crc32(serialize(ksort($position)));

        $nearbyStoreIds = $this->getNearbyStoreIds($position);
        //没有得到任何附近的店铺
        if(!$nearbyStoreIds){
            return array('totalCount'=>0);
        }

        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $storeDao = \DAO\StoreModel::getInstance();

        //获取附近的店铺
        $returnStores = $storeDao->getNearbyStores($where['cityCode'],$nearbyStoreIds);

        if(!$returnStores){
            return array('totalCount'=>0);
        }
        foreach($returnStores as $store){
            $store['storeLabel'] = \Our\Common::getStaticFile($store['storeLabel'],\Our\ImageConst::storeLabel);
            $store['storeDistance'] = \Our\CommonExtension::getDistance($where['lat'],$where['lng'],$store['store_latitude'],$store['store_longitude']);
            unset($store['store_longitude']);
            unset($store['store_latitude']);
            $stores[$store['storeId']] = $store;
        }

        $returnData['totalCount'] = count($stores);
        if($returnData['totalCount']<=\Our\ApiConst::defaultIndexStoreCount){//附近的店铺总数小于等于3家则全部返回,大于三家则随机取三家
            $threeStoreIds = array_keys($stores);
            $threeStores = $stores;
        }else{
            $threeStoreIds = array_rand($stores,\Our\ApiConst::defaultIndexStoreCount);
            $threeStoreIdKeys = array_flip($threeStoreIds);
            $temp = array_diff_key($stores,$threeStoreIdKeys);
            if($temp){
                $threeStores = array_diff_key($stores,$temp);
            }else{
                $threeStores = $stores;
            }
        }
        //$threeStoreIds = array_rand($stores,\Our\ApiConst::defaultIndexStoreCount);
        $nearbyStoresArray['threeStoreIds'] = $threeStoreIds;
        $nearbyStoresArray['stores'] = $stores;
        $nearbyStoreKey = \Our\NameConst::nearbyStoreKeyPrefix . $readisSuffix;
        $storeRedis->update($nearbyStoreKey , $nearbyStoresArray,\Our\ApiConst::oneHour);
        $threeStores = array_values($threeStores);
        return array('totalCount'=>count($stores),'stores'=>$threeStores);

    }

    /**
     * 根据经纬度获取当前位置对应附近店铺
     * @param $position
     */
    private function getNearbyStoreIds($position){
        $readisSuffix = crc32(serialize(ksort($position)));
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix . $readisSuffix;
        $signStoreIds =$storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);

        $serviceStoreKey = \Our\NameConst::serviceStoreIdsPrefix . $readisSuffix;
        $serviceStoreIds = $storeRedis->find($serviceStoreKey, \Our\ApiConst::oneHour);
        if(is_array($signStoreIds)&&is_array($serviceStoreIds)){
            $nearbyStoreIds = array_merge($serviceStoreIds,$signStoreIds);
        }else if(is_array($signStoreIds)){
            $nearbyStoreIds = $signStoreIds;
        }else if(is_array($serviceStoreIds)){
            $nearbyStoreIds = $serviceStoreIds;
        }
        if($nearbyStoreIds&&is_array($nearbyStoreIds)){
            return $nearbyStoreIds;
        }
        return false;

    }

    /**
     * 获取换一批附近的店列表
     * @param $where
     * @return array|bool
     */
    public function getOtherNearbyStores($where){
        $addressDao = \DAO\AddressModel::getInstance();
        $validFlag = $addressDao->getValidAddress($where);
        if(!$validFlag){
            \Error\ErrorModel::throwException($addressDao->errorCode);
        }

        $position['lat'] = $where['lat'];
        $position['lng'] = $where['lng'];
        $position['cityCode'] = $where['cityCode'];
        $readisSuffix = crc32(serialize(ksort($position)));

        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();

        $nearbyStoreKey = \Our\NameConst::nearbyStoreKeyPrefix . $readisSuffix;

        $nearbyStoresArray = $storeRedis->find($nearbyStoreKey, \Our\ApiConst::oneHour);
        if($nearbyStoresArray){
            $stores = $nearbyStoresArray['stores'];
            if(count($stores)<\Our\ApiConst::defaultIndexMinMaxCount){
                $otherStores = $stores;
            }else{
                $oldThreeStoreIds = $nearbyStoresArray['threeStoreIds'];
                $oldThreeStoreIdKeys = array_flip($oldThreeStoreIds);
                $otherStores =array_diff_key($stores,$oldThreeStoreIdKeys);
            }
            if(count($otherStores) <=\Our\ApiConst::defaultIndexStoreCount){
                $threeStores = $otherStores;
                $threeStoreIds = array_keys($threeStores);
            }else{
                $threeStoreIds = array_rand($otherStores,\Our\ApiConst::defaultIndexStoreCount);
                $threeStoreIdKeys = array_flip($threeStoreIds);
                $threeStores = $otherStores;

                $temp =array_diff_key($otherStores,$threeStoreIdKeys);
                if($temp){
                    $threeStores = array_diff_key($otherStores,$temp);
                }
            }
            $nearbyStoresArray['threeStoreIds'] = $threeStoreIds;
            $storeRedis->update($nearbyStoreKey , $nearbyStoresArray,\Our\ApiConst::oneHour);
            $threeStores = array_values($threeStores);
            return array('totalCount'=>count($stores),'stores'=>$threeStores);
        }
        return array('totalCount'=>\Our\ApiConst::zero);
    }
    /**
     * 根据一级分类获取所有二级分类对应推荐店铺
     * @param $where
     * @return bool
     */
    public function getRecommendStores($where,$memberId){
        $condition['lat'] = $where['lat'];
        $condition['lng'] = $where['lng'];
        $condition['cityCode'] = $where['cityCode'];
        $gcId = $where['gcId'];

        \DAO\AddressModel::getInstance()->getValidAddress($condition);
        if(!$gcId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyGcId);
        }
        //获取当前分类对应的全部店铺
        $allStores = $this->getOnlineStoresByGcId($gcId,$condition);
        foreach($allStores as &$store){
            $store['isPurchased'] = \Our\ApiConst::zero;
        }
        $memberStoreIds = null;
        if($memberId){
            $storeMemberDao = \DAO\StoreMemberModel::getInstance();
            $memberStoreIds = \Our\RedisHelper::cachedFunction(\Redis\Db0\StoreMemberRedisModel::getInstance(), array(&$storeMemberDao, 'getList'), array(array('member_id'=>$memberId,'type'=>\Our\ApiConst::storeQrcodeMember),'distinct(store_id) as store_id'), \Our\ApiConst::oneHour,array($memberId));
            //$storeMemberDao->getList(array('member_id'=>$memberId,'type'=>\Our\ApiConst::storeQrcodeMember),'distinct(store_id) as store_id')
        }


        $goodsClassDao = \DAO\GoodsClassModel::getInstance();
        //获取当前分类对应所有店铺信息

        //$storeGoodsClassDao = \DAO\StoreGoodsClassModel::getInstance();
        //签约分类对应店铺
        $signStores = $this->getSignClassStores($gcId,$condition);

        //服务分类对应店铺
        $serviceStores = $this->getServiceClassStores($gcId,$condition);

        //获取签约分类对应店铺
        $expressStores = $this->getExpressStores($gcId,$condition);

        $goodsClassList = $goodsClassDao->getOnlineSecondClassList($gcId);
        if($goodsClassList){
            foreach($goodsClassList as $goodsClass){
                $returnStores = array();
                $returnStores['gcName'] = $goodsClass['gcName'];
                $existStoreIds = null;
                if($signStores&&in_array($goodsClass['gcId'],array_keys($signStores))){//如果当前分类存在对应签约店铺
                    $exitStore = $allStores[$signStores[$goodsClass['gcId']]];
                    $existStoreIds = $signStores[$goodsClass['gcId']];
                }else if($serviceStores&&in_array($goodsClass['gcId'],array_keys($serviceStores))){
                    $exitStore = $allStores[$serviceStores[$goodsClass['gcId']]];
                    $existStoreIds = $serviceStores[$goodsClass['gcId']];
                }else if($expressStores&&in_array($goodsClass['gcId'],array_keys($expressStores))){
                    $exitStore = $allStores[$expressStores[$goodsClass['gcId']]];
                    $existStoreIds = $expressStores[$goodsClass['gcId']];
                }
                if(isset($exitStore)&&$exitStore){
                    $returnStores['stores'][] =$exitStore;
                }
                if($memberStoreIds){
                    $existSignStores = array_intersect($signStores,$memberStoreIds);
                    $existServiceStores = array_intersect($serviceStores,$memberStoreIds);
                    $existExpressStores = array_intersect($expressStores,$memberStoreIds);
                    $purchasedStore = null;
                    if($existSignStores&&in_array($goodsClass['gcId'],array_keys($existSignStores))&&$existSignStores[$goodsClass['gcId']]!=$existStoreIds){
                        $purchasedStore = $allStores[$existSignStores[$goodsClass['gcId']]];
                        $returnStores['stores'][] = $allStores[$existSignStores[$goodsClass['gcId']]];
                    }else if($existServiceStores&&in_array($goodsClass['gcId'],array_keys($existServiceStores))&&$existServiceStores[$goodsClass['gcId']]!=$existStoreIds){
                        $purchasedStore = $allStores[$existServiceStores[$goodsClass['gcId']]];
                        $returnStores['stores'][] = $allStores[$existServiceStores[$goodsClass['gcId']]];
                    }else if($existExpressStores&&in_array($goodsClass['gcId'],array_keys($existExpressStores))&&$existExpressStores[$goodsClass['gcId']]!=$existStoreIds){
                        $purchasedStore = $allStores[$existExpressStores[$goodsClass['gcId']]];
                        $returnStores['stores'][] = $allStores[$existExpressStores[$goodsClass['gcId']]];
                    }
                    if($purchasedStore){
                        $purchasedStore['isPurchased'] = \Our\ApiConst::one;
                        $returnStores['stores'][] = $purchasedStore;
                    }
                }

                if($returnStores['stores']){
                    $return[] = $returnStores;
                }
            }
            if($return){
                return $return;
            }
        }
        return false;

    }

    /**
     * 获取一级分类在签约店铺中的签约分类
     * @param $gcId 一级分类对应gcId
     * @param $position
     */
    public function getSignClassStores($gcId,$position){

        //第一步:获取当前地址对应店铺是否包含当前分类(签约)
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize(ksort($position)));
        $signStoreIds = $storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);
        //签约店铺存在
        if($signStoreIds){
            $return = $this->getStoreClassesByStoreIds($signStoreIds,$gcId);
            return $return;
        }
        return false;
    }

    /**
     * 获取服务分类对应店铺
     * @param $gcId
     * @param $position
     * @return array|bool
     */
    public function getServiceClassStores($gcId,$position){

        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize(ksort($position)));
        $serviceStoreKey = \Our\NameConst::serviceStoreIdsPrefix.crc32(serialize(ksort($position)));
        $signStoreIds = $storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);
        $serviceStoreIds = $storeRedis->find($serviceStoreKey, \Our\ApiConst::oneHour);
        if($signStoreIds&&$serviceStoreIds){
            $serviceStoreIds = array_diff($serviceStoreIds,$signStoreIds);
        }
        //签约店铺存在
        if($serviceStoreIds){
            $return = $this->getStoreClassesByStoreIds($serviceStoreIds,$gcId);
            return $return;
        }
        return false;
    }

    public function getExpressStores($gcId,$position){
        $storeDao = \DAO\StoreModel::getInstance();
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize(ksort($position)));
        $serviceStoreKey = \Our\NameConst::serviceStoreIdsPrefix.crc32(serialize(ksort($position)));
        $signStoreIds = $storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);
        $serviceStoreIds = $storeRedis->find($serviceStoreKey, \Our\ApiConst::oneHour);
        $expressStores = $storeDao->getExpressStores('store_id');
        if($expressStores){
            $expressStoreIds = array_column($expressStores,'store_id');
            if($signStoreIds){
                $expressStoreIds = array_diff($expressStoreIds,$signStoreIds);
            }
            if($serviceStoreIds){
                $expressStoreIds = array_diff($expressStoreIds,$serviceStoreIds);
            }
            if($expressStoreIds){
                $return = $this->getStoreClassesByStoreIds($expressStoreIds,$gcId);
                return $return;
            }
        }
        return false;
    }

    public function getStoreClassesByStoreIds($storeIds,$gcId){
        $signStoreClassSql = ' store_id in ('.implode(',',$storeIds).') and is_charged=1 and gc_parent_id ='.$gcId;
        $qmStoreClassDao = \DAO\QmStoreClassModel::getInstance();
        $signClassStores = $qmStoreClassDao->selectByWhere($signStoreClassSql,'store_id,gc_id');
        //$signClassStores = $storeGoodsClassDao->selectByWhere($signStoreClassSql,'store_id,gc_id');
        if($signClassStores){
            $return = array();
            foreach($signClassStores as $signClass){
                $return[$signClass['gc_id']] = $signClass['store_id'];
            }
            return $return;
        }
        return false;
    }

    /**
     * 根据一级分类获取当前一级分类对应的全部店铺
     * @param $gcId 一级分类ID
     * @return array|bool 店铺列表
     * @throws \Our\Exception
     */
    public function getOnlineStoresByGcId($gcId,$condition){
        $lat = $condition['lat'];
        $lng = $condition['lng'];
        $storeDao = \DAO\StoreModel::getInstance();
        //获取当前分类对应店铺ID
        $qmStoreClassDao = \DAO\QmStoreClassModel::getInstance();
        $storeIds = $qmStoreClassDao->getStoreIdsByWhere($gcId);
        if(!$storeIds){
            return false;
        }
        $field = 'store_id as storeId,store_name as storeName,store_label as storeLabel,store_intro as storeIntro,store_longitude,store_latitude';
        $where = ' and store_id in('.implode(',',$storeIds).')';
        sort($storeIds);
        $stores = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeDao, 'getOnlineStores'), array($where, $field), \Our\ApiConst::oneHour);
        if($stores){
            $storeList = array();
            foreach($stores as $store){
                $store['storeDistance'] = \Our\CommonExtension::getDistance($lat,$lng,$store['store_latitude'],$store['store_longitude']);
                unset($store['store_longitude']);
                unset($store['store_latitude']);
                $store['storeLabel'] = \Our\Common::getStaticFile($store['storeLabel'], \Our\ImageConst::storeLabel);
                $storeList[$store['storeId']] = $store;
            }
            return $storeList;
        }
        return false;
    }
    

    /**
     * 获取热销专区的商品
     * @param $storeId
     * @param null $memberId
     */
    public function getHotSaleGoods($param,$memberId = null){
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        $limit = array(0,3);
        $where[] = "store_id={$storeId}";
        $order[] = ['sale_num','DESC'];
        $commonDAO = \DAO\GoodsCommonModel::getInstance();
        //$activities = $this->isJoin($storeId,$memberId);
        $activities = \DAO\SaleMemberModel::getInstance()->isJoinStore($storeId,$memberId);
        if($activities === false){
            $field = 'goods_commonid AS goodsCommonId,goods_name AS goodsName,goods_price as goodsPrice,goods_marketprice AS goodsMarketPrice,goods_image AS goodsImage,goods_jingle AS goodsCopywriting';
            $list = \Our\RedisHelper::cachedFunction(\Redis\Db4\GoodsCommonRedisModel::getInstance(),array(&$commonDAO, 'getGoodsList'),array($where,$field,$limit,$order),\Our\ApiConst::oneDaySecond,array($storeId));
        }else{
            $activities = array_keys($activities);
            $field = 'han_goods_common.goods_commonid AS goodsCommonId,goods_name AS goodsName,goods_price,goods_marketprice AS goodsMarketPrice,goods_image AS goodsImage,goods_jingle AS goodsCopywriting,IFNULL(discount_price,han_goods_common.goods_price) AS goodsPrice';
            $list = \Our\RedisHelper::cachedFunction(\Redis\Db4\GoodsCommonRedisModel::getInstance(),array(&$commonDAO, 'getListWithSale'),array($where,$field,$activities,$limit,$order),\Our\ApiConst::oneDaySecond,array($storeId));
        }
        $goods = [];
        if(is_array($list) && !empty($list)){
            foreach ($list as $k=>$v){
                unset($v['goods_price']);
                switch ($k) {
                    case 0:
                        $v['goodsImage'] = \Our\ImageUtil::getGoodsImgUrl($v['goodsImage'],300, 410);
                        break;
                    case 1:
                        $v['goodsImage'] = \Our\ImageUtil::getGoodsImgUrl($v['goodsImage'],380, 198);
                        break;
                    case 2:
                        $v['goodsImage'] = \Our\ImageUtil::getGoodsImgUrl($v['goodsImage'],380, 198);
                        break;
                    default:
                        $v['goodsImage'] = \Our\ImageUtil::getGoodsImgUrl($v['goodsImage'],380, 198);
                        break;
                }
                $v['goodsPrice'] = (int)$v['goodsPrice'];
                $goods[] = $v;
            }
        }
        return $goods;
    }
    public function getRecommendClass($storeId){
        $grade = 1;
        $classList = \DAO\GoodsClass\GoodsClassImageModel::getInstance()->getList(array('store_id'=>$storeId,'is_recommend'=>1),'gc_id');
        if(!$classList){
            $classList = \DAO\QmStoreClassModel::getInstance()->selectByWhere(array('store_id'=>$storeId,'is_charged'=>1),'gc_parent_id',array(0,5));
            if($classList) {
                $ids = array_column($classList,'gc_parent_id');
                $ids = array_unique($ids);
                if(count($ids) <= 1) {
                    $grade = 2;
                    $ids = array_column($classList,'gc_id');
                }
            }
        }else{
            $classList && $ids = array_column($classList,'gc_id');
        }
        $gc_names = [];
        if($ids){
            $gc_names = \DAO\GoodsClassModel::getInstance()->getList('gc_id AS classId,gc_name AS gcName','gc_id in('.implode(',',$ids).')');
            foreach ($gc_names as &$gc_name) {
                $gc_name['grade'] = $grade;
            }
        }
        return $gc_names;
    }
    public function getRecommendClassCache($param){
        $storeId = intval($param['storeId']);
        if(!$storeId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyStoreId);
        }
        $gc_names = \Our\RedisHelper::cachedFunction(\Redis\Db4\GoodsClassImageRedisModel::getInstance(),array(&$this, 'getRecommendClass'),array($storeId),\Our\ApiConst::oneDaySecond,array($storeId));
        return $gc_names;
    }

    /**
     * 删除首页店铺及分类缓存
     * @param $cityCode
     */
    public function deleteStoreAndStoreClassCacheByCitycode($cityCode){
        \DAO\QmStoreClassModel::getInstance()->delStoreClassesCache($cityCode);
        $storeDao = \DAO\StoreModel::getInstance();
        $storeDao->delNearbyStoresCache($cityCode);
        $storeDao->delStoresCacheByCityCode($cityCode);
    }

    /**
     */
    private static $_instance = null;

    /**
     * 单例模式获取类实例
     *
     */
    public static function getInstance() {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }

}
