<?php

namespace Business\Store;
use Our\ApiConst;
use Our\DbNameConst;

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


    public function init() {
    }


    /**
     * 更新店铺分布数据
     * @return bool
     * User: King <358887571@qq.com>
     * Date: 2018/11/30 0030
     * Time: 下午 4:27
     */
    public function updateStatStore(){
        $beginTime = file_get_contents($this->baseDir . \Our\PathConst::storeStatTime, TIMESTAMP);
        $beginTime = $beginTime ? $beginTime : ApiConst::zero;
        $endTime = TIMESTAMP;
        $result = true;
        $storeDao = \DAO\StoreModel::getInstance();
        $statDao = \DAO\StatStoreModel::getInstance(DbNameConst::masterDBConnectName);

        //更新店铺基础数据
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select se.store_id from han_store_extend se where se.gmt_update > '.$beginTime.' )';
        $field = 'store_id,store_name,store_state,store_time,store_end_time,province_id,city_id,area_id,(select se.cashed_deposit from han_store_extend se where se.store_id=han_store.store_id) cashed_deposit';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'extend in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺经营分类数据
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select qs.store_id from han_qm_store_class qs where qs.gmt_update > '.$beginTime.' or (qs.deadline>'.$beginTime.' and qs.deadline<='.$endTime.'))';
        $field = 'store_id, (select count(qs.store_id) from han_qm_store_class qs where qs.is_charged<>0 and qs.store_id=han_store.store_id) class_style1_count, (select count(qs.store_id) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id) class_style2_count, if((store_state=1 and store_end_time>=0), ifnull((select sum(qs.service_fee) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id), 0), ifnull((select sum(qs.service_fee) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id and qs.deadline>=0), 0)) service_fee';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'class in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺关注信息
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select fs.store_id from han_favorites_store fs where fs.fav_time > '.$beginTime.')';
        $field = 'store_id,(select count(fs.store_id) from han_favorites_store fs where fs.fav_type=1 and fs.store_id=han_store.store_id) fav_total,(select count(fs.store_id) from han_favorites_store fs where fs.fav_type=1 and fs.fav_from=3 and fs.store_id=han_store.store_id) fav3_total';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'favorite in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺有效订单信息
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select ss.store_id from han_store_statistics ss where ss.add_time > '.$beginTime.')';
        $field = 'store_id,(select t.order_count from han_store_statistics t where t.store_id=han_store.store_id limit 1) order_count,(select t.order_total from han_store_statistics t where t.store_id=han_store.store_id limit 1) order_total';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'statistics in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺订单超时信息
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select o.store_id from han_order o where o.gmt_update > '.$beginTime.')';
        $field = 'store_id,(select count(*) from han_order o where o.store_id=han_store.store_id) all_order_count,(select count(*) from han_order o where o.is_effective=1 and o.store_id=han_store.store_id) expire_order_count';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'statistics in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_date['expire_order_percent'] = intval($val['expire_order_count']/$val['all_order_count']*100);
                $update_data['upd_time'] = $endTime;
                unset($update_data['all_order_count']);
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺退货退款信息
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select rr.store_id from han_refund_return rr where rr.gmt_update > '.$beginTime.')';
        $field = 'store_id,(select count(distinct t.order_id) from han_refund_return t where t.store_id=han_store.store_id and t.seller_state!=3) refund_order_count,(select sum(t.refund_amount) from han_refund_return t where t.seller_state!=3 and t.store_id=han_store.store_id) refund_order_total';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'refund in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //更新店铺举报信息
        $where = 'store_id in (select ss.store_id from han_stat_store ss) and store_id in (select t.seller_id from han_report t where t.report_time > '.$beginTime.')';
        $field = 'store_id,(select count(*) from han_report t where t.seller_id=han_store.store_id) report_count';
        if($datas = $storeDao->getStores($where, $field)) {
            echo 'favorite in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $update_data = $val;
                $update_data['upd_time'] = $endTime;
                unset($update_data['store_id']);
                $where = 'store_id='.$val['store_id'];
                if(!$statDao->update($where, $update_data)){
                    $result = false;
                }
            }
        }

        //处理新店铺信息
        $where = 'store_id not in (select ss.store_id from han_stat_store ss) and is_own_shop=0';
        $field = 'store_id, store_name, store_state,store_time,store_end_time,province_id,city_id,area_id,(select se.cashed_deposit from han_store_extend se where se.store_id=han_store.store_id) cashed_deposit';
        $field .= ',(select count(qs.store_id) from han_qm_store_class qs where qs.is_charged<>0 and qs.store_id=han_store.store_id) class_style1_count, (select count(qs.store_id) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id) class_style2_count, if((store_state=1 and store_end_time>=0), ifnull((select sum(qs.service_fee) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id), 0), ifnull((select sum(qs.service_fee) from han_qm_store_class qs where qs.is_charged<>0 and qs.class_style=2 and qs.store_id=han_store.store_id and qs.deadline>=0), 0)) service_fee';
        $field .= ',(select count(fs.store_id) from han_favorites_store fs where fs.fav_type=1 and fs.store_id=han_store.store_id) fav_total,(select count(fs.store_id) from han_favorites_store fs where fs.fav_type=1 and fs.fav_from=3 and fs.store_id=han_store.store_id) fav3_total';
        $field .= ',(select t.order_count from han_store_statistics t where t.store_id=han_store.store_id limit 1) order_count,(select t.order_total from han_store_statistics t where t.store_id=han_store.store_id limit 1) order_total';
        $field .= ',(select count(*) from han_order o where o.store_id=han_store.store_id) all_order_count,(select count(*) from han_order o where o.is_effective=1 and o.store_id=han_store.store_id) expire_order_count';
        $field .= ',(select count(distinct t.order_id) from han_refund_return t where t.store_id=han_store.store_id and t.seller_state!=3) refund_order_count,(select sum(t.refund_amount) from han_refund_return t where t.seller_state!=3 and t.store_id=han_store.store_id) refund_order_total';
        $field .= ',(select count(*) from han_report t where t.seller_id=han_store.store_id) report_count';

        if($datas = $storeDao->getStores($where, $field)) {   //插入报表
            echo 'not in:'.count($datas);
            foreach ($datas as $key=>$val) {
                $insert_data = $val;
                $insert_data['expire_order_percent'] = $val['all_order_count'] ? intval
                ($val['expire_order_count']/$val['all_order_count']*100) : 0;
                $insert_data['upd_time'] = $endTime;
                unset($insert_data['all_order_count']);

                if(!$statDao->insert($insert_data)){
                    echo 'insert fail'.var_export($val, true)."\n";
                    $result = false;
                }
            }
        }

        if($result) {   //商品报表更新成功
            file_put_contents($this->baseDir . \Our\PathConst::storeStatTime, $endTime);
        }
        return $result;
    }

    /**
     * 获取店铺首页渲染信息
     * 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);
        }

        list($storeInfo,$storeLabel) = \DAO\StoreModel::getInstance()->get($storeId,true);
        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) {
                        $sale_act = \DAO\SaleActivityModel::getInstance()->getOne(array('sale_act_id'=>$sale['sale_act_id'],'sale_act_state'=>1),'*');
                        if($sale_act && $sale_act['sale_start_date'] <= time() && $sale_act['sale_end_date'] >= time()){
                            $result = \DAO\SaleMemberModel::getInstance()->insertOrUpdate(array('sale_id'=>$sale['member_id'],'sale_act_id'=>$sale['sale_act_id'],'member_id'=>$memberId,'store_id'=>$sale_act['store_id']));
                            \Redis\Db4\SaleActivityRedisModel::getInstance()->tableDel('storeId:'.$storeId);
                            $saleMemberDao = \DAO\SaleMemberModel::getInstance();
                            \Our\RedisHelper::delCachedFunction(\Redis\Db4\SaleMemberRedisModel::getInstance(),array(&$saleMemberDao, 'getActAndSale'),array(array('han_sale_member.store_id'=>$storeId,'han_sale_member.member_id'=>$memberId),'han_sale_activity.sale_act_id,han_sale_activity.sale_start_date,han_sale_activity.sale_end_date,han_sale_member.sale_id'),array($storeId));
                        }
                    }
                }
                $storeMembers = array();
                $storeMember = array();
                $storeMember['store_id'] = $storeId;
                $storeMember['member_id'] = $memberId;
                $storeMember['fav_from'] = \Our\ApiConst::scanFavor;
                $storeMember['fav_type'] = \Our\ApiConst::one;
                $storeMembers[] = $storeMember;
                $favoritesStoreDao = \DAO\FavoritesStoreModel::getInstance();
                $one = $favoritesStoreDao->getOne('store_id',array('store_id'=>$storeId,'member_id'=>$memberId,'fav_type'=>\Our\ApiConst::one),'');
                $result = $favoritesStoreDao->insertAll($storeMembers);
                //删除关联店铺缓存
                $favoritesRedis = \Redis\Db6\FavoritesStoreRedisModel::getInstance();
                $favoritesRedis->tableDelAll($favoritesRedis->tableKeys('myFavoritesStore'.$favoritesRedis::DELIMITER.$memberId.'_'));
                if($result && !$one) {
                    $favoritesStoreDao->updateStoreCollecitonsCache(array($storeId),$memberId,2);
                }
            }else{
                $sess=\Yaf\Session::getInstance();
                $scan_store_ids = $sess->get('scan_store_ids');
                if($scan_store_ids){
                    if(is_array($scan_store_ids)){//兼容历史数据,如果有历史数据
                        $scan_store_ids = implode(',',$scan_store_ids);
                    }
                    if(strpos(','.$scan_store_ids.',',','.$storeId.',')===false){
                        $scan_store_ids .= ','.$storeId;
                    }
                }else{
                    $scan_store_ids = ''.$storeId;
                }
                $sess['scan_store_ids'] = $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;

        //位置相关
        if($address) {
            $lng = $address['lng'];
            $lat = $address['lat'];
        }else{
            $lng = $param['lng'];
            $lat = $param['lat'];
        }
        $defaultDeliveryTime = 0;
        $in_store_service_flag=0;
        if($lng && $lat){
            $location = array('lat'=>$lat,'lng'=>$lng);
            $in_store_service = \Store\StoreUtil::getInstance()->checkAddressInServiceArea($location,$storeId);
            $in_store_service && $in_store_service_flag = 1;
            $distince = \Our\CommonExtension::getDistance($lat,$lng,$storeInfo['store_latitude'],$storeInfo['store_longitude']);
            if($in_store_service_flag) {
                $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){
                    $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;
            }
        }
        //营业时间
        if($storeInfo['store_start_time'] && $storeInfo['store_close_time']) {
            if($storeInfo['store_start_time'] == $storeInfo['store_close_time']) {
                $businessHours = '全天';
            }elseif ($storeInfo['store_start_time'] > $storeInfo['store_close_time']) {
                $businessHours = $storeInfo['store_start_time'].' - 次日'.$storeInfo['store_close_time'];
            }else{
                $businessHours = $storeInfo['store_start_time'].' - '.$storeInfo['store_close_time'];
            }
        }else{
            $businessHours = '';
        }

        $sellerDistribution = $storeInfo['seller_distribution'];
        $buyerDistribution = $storeInfo['buyer_distribution'];
        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'=>1,'adv'=>$adv,'memberId'=>$storeInfo['member_id'],'businessHours'=>$businessHours,'sellerDistribution'=>$sellerDistribution,'buyerDistribution'=>$buyerDistribution,'bannerColor'=>'#ffa92f','isClose'=>$storeInfo['isClose']);
    }

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

        list($storeInfo,$storeLabel) = \DAO\StoreModel::getInstance()->get($storeId,true,$flag);
        //展示图片
//        $detailImg = [];
//        if($storeInfo['store_detail_image']){
//            $storeDetailImg = unserialize($storeInfo['store_detail_image']);
//            if($storeDetailImg && is_array($storeDetailImg)){
//                foreach ($storeDetailImg as $v){
//                    if($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'];
        }
        $address = preg_replace("/\s/",'',$address);
        //营业时间
        if($storeInfo['store_start_time'] && $storeInfo['store_close_time']) {
            if($storeInfo['store_start_time'] == $storeInfo['store_close_time']) {
                $businessHours = '全天';
            }elseif ($storeInfo['store_start_time'] > $storeInfo['store_close_time']) {
                $businessHours = $storeInfo['store_start_time'].' - 次日'.$storeInfo['store_close_time'];
            }else{
                $businessHours = $storeInfo['store_start_time'].' - '.$storeInfo['store_close_time'];
            }
        }else{
            $businessHours = '';
        }
        //店铺经营分类
        $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[] = htmlspecialchars_decode($v['gc_name']);
            }
        }
        list($qualificationPics,$detailImg) = $this->getStoreQualification($storeId,$storeInfo['member_id']);
        return array('storeName'=>$storeInfo['store_name'],'storeLabel'=>$storeLabel,'fansCount'=>\DAO\FavoritesStoreModel::getInstance()->getFavoritesStoreCountByStoreId($storeId),'clazz'=>$returnClass,'address'=>$address,'storePhone'=>$storeInfo['store_phone'],'openingHours'=>$businessHours,'storeService'=>$storeInfo['store_notice'],"qualificationImage"=>$qualificationPics,'showImage'=>$detailImg);
    }
    public function getRecommendGoodsCache($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);
        if($activities) {
            $activities = array_keys($activities);
        }
        $recommendGoods = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreGoodsClassRedisModel::getInstance(),array(&$this, 'getRecommendGoods'),array($storeId,$activities),\Our\ApiConst::oneDaySecond,array(intval($param['storeId'])));
        return $recommendGoods;
    }
    /**
     * 获取店铺首页推荐商品
     * @param $param
     */
    public function getRecommendGoods($storeId,$activities){
        $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(empty($activities)){
                $tempGoods = $goodsCommonDAO->getGoodsList(array('goods_commonid in('.implode(',',$goodsIds).')'),'goods_name,goods_image,goods_price as goodsPrice,goods_marketprice,goods_commonid');
            }else{
                $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,IFNULL(discount_price,han_goods_common.goods_price) AS goodsPrice',$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']]['goodsPrice'],
                            '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)
                            ];
                        }
                    }
                }
                $tempRecommendGoods = array();
                foreach($tempStcs as $tempStc){
                    $tempRecommendGoods[] = $recommendGoods[$tempStc['stc_id']];
                }
                $recommendGoods = $tempRecommendGoods;
            }
        }
//        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 < 3 ; $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){
                    $result = \Our\Common::getStaticFile($file_name,\Our\ImageConst::feedback);
                    $imgArr[] = pathinfo($result)['basename'];
                }
            }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();
        $one = $FavoritesStoreInstance->getOne('store_id',array('store_id'=>$storeId,'member_id'=>$memberId,'fav_type'=>1));
        if($one) {
            return true;
        }
        $return = $FavoritesStoreInstance->insertOrUpdate(array('member_id'=>$memberId,'store_id'=>$storeId,'fav_time'=>time(),'fav_type'=>1,'fav_from'=>1));

        if($return){
            $FavoritesStoreInstance->updateStoreCollecitonsCache(array($storeId),$memberId,2);
            return true;
        }
    }

    /**
     * 上传当前用户的关注店铺
     * @param $param
     * @param $memberId
     */
    public function updateFavoritesStore($param,$memberId){
//        if(!(isset($param['storeId'])&&$param['storeId'])){
//            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyScanStoreId);
//        }
//        $storeId = trim($param['storeId']);
//        $storeInfo = \DAO\StoreModel::getInstance()->get($storeId,false);
//        if(!$storeInfo){
//            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyScanStoreInfo);
//        }
//        $storeMembers = array();
//        $storeMember = array();
//        $storeMember['store_id'] = $storeId;
//        $storeMember['member_id'] = $memberId;
//        $storeMember['fav_from'] = \Our\ApiConst::scanFavor;
//        $storeMember['fav_type'] = \Our\ApiConst::one;
//        $storeMembers[] = $storeMember;
//        $favoritesStoreDao = \DAO\FavoritesStoreModel::getInstance();
//
//        $one = $favoritesStoreDao->getOne('store_id',array('store_id'=>$storeId,'member_id'=>$memberId,'fav_type'=>\Our\ApiConst::one),'');
//        if(!$one) {
//            $result = $favoritesStoreDao->insertAll($storeMembers);
//            if(!$result){
//                \Error\ErrorModel::throwException(\Error\CodeConfigModel::saveScanStoreInfoFailed);
//            }
//            $favoritesStoreDao->updateStoreCollecitonsCache(array($storeId),$memberId,2);
//            $favoritesDao = \DAO\FavoritesStoreModel::getInstance();
//            \Our\RedisHelper::delCachedFunction(\Redis\Db6\FavoritesStoreRedisModel::getInstance(),array(&$favoritesDao, 'getOne'),array(),array($memberId));
//
//        }


        return true;

    }
    public function getStoreQualification($storeId,$memberId) {
        $pics = \DAO\Store\QmStoreApplyClassModel::getInstance()->getApplyPicCache($storeId,'file_name');
        $join = \DAO\Store\StoreJoininModel::getInstance()->getOneByMemberIdCache($memberId,'business_licence_photo,shop_front_photo,shop_photo');
        $join['business_licence_photo'] && $pics[] =\Our\Common::getStaticFile($join['business_licence_photo'], \Our\ImageConst::Register, 'ossHost');
        $qualificationPics = \DAO\Store\QmStoreApplyClassModel::getInstance()->addWaterMark($pics);
        $showImg = [];
        $join['shop_front_photo'] && $showImg[] = \Our\Common::getStaticFile($join['shop_front_photo'], \Our\ImageConst::Register, 'ossHost');
        if($shop_photo = unserialize($join['shop_photo'])) {
            foreach ($shop_photo as $v) {
                $v && $showImg[] = \Our\Common::getStaticFile($v, \Our\ImageConst::Register, 'ossHost');
            }
        }
        return array($qualificationPics,$showImg);
    }
    /**
     * 获取搜索页推荐关键字
     * @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,$nearByFlag=false,$returnStoreListFlag=false){
        $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'];
        ksort($position);
        $readisSuffix = crc32(serialize($position));
        $nearbyStoreIds = $this->getNearbyStoreIds($position);
        if($nearByFlag&&!$nearbyStoreIds){ //如果是换一批调用当前方法 ,没有从缓存得到福建的店铺 ,则直接再次获取
            $signStoreInfo = \Business\Goods\GoodsClassServiceModel::getInstance()->getSignStoreInfo($where);
            $nearbyStoreIds = $signStoreInfo['signStoreIds'];//当前位置签约店铺ID
        }
        //没有得到任何附近的店铺
        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);
        if($returnStoreListFlag){
            return $stores;
        }
        return array('totalCount'=>count($stores),'stores'=>$threeStores);

    }

    /**
     * 根据经纬度获取当前位置对应附近店铺
     * @param $position
     */
    private function getNearbyStoreIds($position){
        ksort($position);
        $readisSuffix = crc32(serialize($position));
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix . $readisSuffix;
        $signStoreIds =$storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);
        if(!$signStoreIds){
            $signStoreInfo = \Business\Goods\GoodsClassServiceModel::getInstance()->getSignStoreInfo($position);
            $signStoreIds = $signStoreInfo['signStoreIds'];//当前位置签约店铺ID
        }
        //$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(isset($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'];
        ksort($position);
        $readisSuffix = crc32(serialize($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);
        }else{
            return $this->getNearbyStores($where,true);
        }
    }
    /**
     * 根据一级分类获取所有二级分类对应推荐店铺
     * @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;
        }
        $memberStores = $this->getPurchasedStoreClass($memberId,$gcId);


        $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'] = htmlspecialchars_decode($goodsClass['gcName']);
                //$returnStores['gcImg'] = \Our\Common::getStaticFile(\Our\ImageConst::categoryHeadPicPrefix.$goodsClass['gcId'].\Our\NameConst::jpgSuffix,\Our\ImageConst::defaultPath);
                $returnStores['gcImg'] = \Our\Common::getStaticFile('category-headpic-default.jpg',\Our\ImageConst::defaultPath);
                $existStoreIds = null;
                $returnStores['stores'] = null;
                $exitStore = array();
                $purchasedStore = array();
                if($signStores&&in_array($goodsClass['gcId'],array_keys($signStores))){//如果当前分类存在对应签约店铺
                    $exitStore = $allStores[$signStores[$goodsClass['gcId']]];
                }
                if(empty($exitStore)&&$serviceStores&&in_array($goodsClass['gcId'],array_keys($serviceStores))){
                    $exitStore = $allStores[$serviceStores[$goodsClass['gcId']]];
                }

                /*if(empty($exitStore)&&$expressStores&&in_array($goodsClass['gcId'],array_keys($expressStores))){
                    $exitStore = $allStores[$expressStores[$goodsClass['gcId']]];
                }*/
                if($memberStores){
                    if($memberStores&&in_array($goodsClass['gcId'],array_keys($memberStores))){
                        $purchasedStore = $allStores[$memberStores[$goodsClass['gcId']]];
                    }
                    if($purchasedStore){
                        $purchasedStore['isPurchased'] = \Our\ApiConst::one;
                    }
                }
                if($exitStore&&$purchasedStore&&$exitStore['storeId']==$purchasedStore['storeId']){
                    $returnStores['stores'][] = $exitStore;
                }else{
                    if(isset($exitStore)&&$exitStore){
                        $returnStores['stores'][] =$exitStore;
                    }
                    if(isset($purchasedStore)&&$purchasedStore){
                        $returnStores['stores'][] =$purchasedStore;
                    }
                }
                if($returnStores['stores']){
                    foreach($returnStores['stores'] as $key => $tempStore){
                        $tempDistance[$key] = $tempStore['storeDistance'];
                    }
                    array_multisort($tempDistance, SORT_ASC, $returnStores['stores']);
                    $return[] = $returnStores;
                }
            }
            if($return){
                /*var_dump(json_encode($return));
                $tempReturn = array();
                foreach($return as $tempVal){
                    $distance = min(array_column($tempVal['stores'],'storeDistance'));
                    $tempReturn[$distance] = $tempVal;
                }
                ksort($tempReturn);
                $return = array_values($tempReturn);*/
                return $return;
            }
        }
        return false;

    }

    public function getPurchasedStoreClass($memberId,$gcId){
        if(!$memberId){
            return array();
        }
        $favoritesStoreDao = \DAO\FavoritesStoreModel::getInstance();
        $memberStoreList = \Our\RedisHelper::cachedFunction(\Redis\Db6\FavoritesStoreRedisModel::getInstance(), array(&$favoritesStoreDao, 'selectList'), array(array('member_id'=>$memberId,'fav_from'=>\Our\ApiConst::scanFavor),'store_id,fav_time'), \Our\ApiConst::oneHour,array($memberId));
        if(!$memberStoreList){
            return array();
        }
        $memberStoreIds = array_column($memberStoreList,'store_id');
        $signStoreClassSql = ' store_id in ('.implode(',',$memberStoreIds).') and is_charged=1 and gc_parent_id ='.$gcId;
        $qmStoreClassDao = \DAO\QmStoreClassModel::getInstance();

        $signClassStores = \Our\RedisHelper::cachedFunction(\Redis\Db6\QmStoreClassRedisModel::getInstance(), array(&$qmStoreClassDao, 'selectByWhere'), array($signStoreClassSql,'store_id,gc_id'), \Our\ApiConst::oneHour,array('gcId_'.$gcId.'member_'.$memberId));
        //$signClassStores = $qmStoreClassDao->selectByWhere($signStoreClassSql,'store_id,gc_id');
        if($signClassStores){
            $return = array();
            foreach($memberStoreList as $tempStore){
                $storeFlag = false;
                foreach($signClassStores as $signClass){
                    if($tempStore['store_id']==$signClass['store_id']){
                        if($storeFlag){
                            break;
                        }
                        if(isset($return[$signClass['gc_id']])&&$return[$signClass['gc_id']]){
                            continue;
                        }
                        $return[$signClass['gc_id']] = $signClass['store_id'];
                        $storeFlag = true;
                    }
                }
            }

            return $return;
        }
        return false;
    }

    /**
     * 获取一级分类在签约店铺中的签约分类
     * @param $gcId 一级分类对应gcId
     * @param $position
     */
    public function getSignClassStores($gcId,$position){
        ksort($position);
        //第一步:获取当前地址对应店铺是否包含当前分类(签约)
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize($position));
        $signStoreIds = $storeRedis->find($signStoreKey, \Our\ApiConst::oneHour);
        if(!$signStoreIds){
            $signStoreInfo = \Business\Goods\GoodsClassServiceModel::getInstance()->getSignStoreInfo($position);
            if($signStoreInfo){
                $signStoreIds = $signStoreInfo['signStoreIds'];
            }
        }
        //签约店铺存在
        if($signStoreIds){
            $return = $this->getSignStoreClassesByStoreIds($signStoreIds,$gcId,$position);
            return $return;
        }
        return false;
    }

    /**
     * 获取服务分类对应店铺
     * @param $gcId
     * @param $position
     * @return array|bool
     */
    public function getServiceClassStores($gcId,$position){
        ksort($position);
        $storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize($position));
        $serviceStoreKey = \Our\NameConst::serviceStoreIdsPrefix.crc32(serialize($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){
            $serviceStoreIds = \Business\Goods\GoodsClassServiceModel::getInstance()->getServiceStoreIds($position);
        }
        //服务店铺存在
        if($serviceStoreIds){
            $return = $this->getStoreClassesByStoreIds($serviceStoreIds,$gcId);
            return $return;
        }
        return false;
    }

    public function getExpressStores($gcId,$position){

        ksort($position);
        $storeDao = \DAO\StoreModel::getInstance();
        /*$storeRedis = \Redis\Db6\StoreRedisModel::getInstance();
        $signStoreKey = \Our\NameConst::signStoreIdsPrefix.crc32(serialize($position));
        $serviceStoreKey = \Our\NameConst::serviceStoreIdsPrefix.crc32(serialize($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;
    }


    /**
     * 获取签约店铺的签约分类
     * @param $signStoreIds
     * @param $gcId
     * @return array|bool
     */
    public function getSignStoreClassesByStoreIds($signStoreIds,$gcId,$position){
        $signStoreClassSql = ' store_id in ('.implode(',',$signStoreIds).') and gc_parent_id ='.$gcId;
        $qmStoreClassDao = \DAO\QmStoreClassModel::getInstance();
        $signClassStores = $qmStoreClassDao->getStoreSignClasses($signStoreClassSql,'store_id,gc_id,sign_scope');
        //$signClassStores = $storeGoodsClassDao->selectByWhere($signStoreClassSql,'store_id,gc_id');
        if($signClassStores){
            $return = array();
            foreach($signClassStores as $signClass){
                $inAreaFlag = \Our\CommonExtension::locationInArea($position['lat'],$position['lng'],$signClass['sign_scope']);
                if($inAreaFlag){
                    if(isset($return[$signClass['gc_id']])){
                        continue;
                    }
                    $return[$signClass['gc_id']] = $signClass['store_id'];
                }
            }
            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();
            shuffle($signClassStores);
            $gcIds = array_unique(array_column($signClassStores,'gc_id'));
            foreach($gcIds as $tempGcId){
                if(isset($return[$tempGcId])&&$return[$tempGcId]){
                    break;
                }
                foreach($signClassStores as $signClass){
                    if($tempGcId==$signClass['gc_id']){
                        if(isset($return[$signClass['gc_id']])&&$return[$signClass['gc_id']]){
                            break;
                        }
                        $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 = ' store_id in('.implode(',',$storeIds).')';
        sort($storeIds);
        $stores = \Our\RedisHelper::cachedFunction(\Redis\Db6\StoreRedisModel::getInstance(), array(&$storeDao, 'getOnlineStores'), array($where, $field), \Our\ApiConst::oneHour,array($condition['cityCode']));
        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\ImageUtil::getStoreLabel($store['storeLabel'], \Our\ImageConst::storeLabel,213);
                $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(empty($activities)){
            $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);
        $platformFirstClassDao = \DAO\GoodsClass\PlatformFirstClassModel::getInstance();
        \Our\RedisHelper::delCachedFunction(\Redis\Db3\PlatformFirstClassRedisModel::getInstance(),array(&$platformFirstClassDao, 'getList'),array(),array());
        return true;
    }

    public function editQmStoreClass(){
        $qmStoreClassDao = \DAO\QmStoreClassModel::getInstance();
        $qmStoreClassList = $qmStoreClassDao->selectByWhere(array('sign_rang'=>array('gt',0)));
        if($qmStoreClassList){
            foreach($qmStoreClassList as $qmObj){
                $qmStoreClassStr =  '[';
                $qmStoreClassStr .= '{"lng":'.($qmObj['longitude']+0.001).',"lat":'.($qmObj['latitude']-0.001).'},{"lng":'.($qmObj['longitude']+0.001).',"lat":'.($qmObj['latitude']+0.001).'},{"lng":'.($qmObj['longitude']-0.001).',"lat":'.($qmObj['latitude']+0.001).'},{"lng":'.($qmObj['longitude']-0.001).',"lat":'.($qmObj['latitude']-0.001).'}';
                $qmStoreClassStr .= ']';
                $result = $qmStoreClassDao->update(array('sign_scope'=>$qmStoreClassStr),array('id'=>$qmObj['id']));
            }
        }
    }

    public function deleteQmStoreClassByGcParentId($gcParentId){
        $platformFirstClassDao = \DAO\GoodsClass\PlatformFirstClassModel::getInstance();
        \Our\RedisHelper::delCachedFunction(\Redis\Db3\PlatformFirstClassRedisModel::getInstance(),array(&$platformFirstClassDao, 'getList'),array(),array());

        \Our\RedisHelper::delCachedFunction(\Redis\Db6\QmStoreClassRedisModel::getInstance(), array(\DAO\QmStoreClassModel::getInstance(), 'selectByWhere'),array(),array('*gcId_'.$gcParentId.'*'));
        $classStoreModel = \DAO\Store\ClassStoreModel::getInstance();
        \Our\RedisHelper::delCachedFunction(\Redis\Db6\ClassStoreRedisModel::getInstance(), array(&$classStoreModel, 'getList'), array(),array($gcParentId));
        return true;
    }
    public function growStores(){
        $cityCodes=array('010','021','022','023','852','853','0310','0311','0312','0313','0314','0315','0316','0317','0318','0319','0335','0570','0571','0572','0573','0574','0575','0576','0577','0578','0579','0580','024','0410','0411','0412','0413','0414','0415','0416','0417','0418','0419','0421','0427','0429','027','0710','0711','0712','0713','0714','0715','0716','0717','0718','0719','0722','0724','0728','025','0510','0511','0512','0513','0514','0515','0516','0517','0517','0518','0519','0523','0470','0471','0472','0473','0474','0475','0476','0477','0478','0479','0482','0483','0790','0791','0792','0793','0794','0795','0796','0797','0798','0799','0701','0350','0351','0352','0353','0354','0355','0356','0357','0358','0359','0930','0931','0932','0933','0934','0935','0936','0937','0938','0941','0943','0530','0531','0532','0533','0534','0535','0536','0537','0538','0539','0450','0451','0452','0453','0454','0455','0456','0457','0458','0459','0591','0592','0593','0594','0595','0595','0596','0597','0598','0599','020','0751','0752','0753','0754','0755','0756','0757','0758','0759','0760','0762','0763','0765','0766','0768','0769','0660','0661','0662','0663','028','0810','0811','0812','0813','0814','0816','0817','0818','0819','0825','0826','0827','0830','0831','0832','0833','0834','0835','0836','0837','0838','0839','0840','0730','0731','0732','0733','0734','0735','0736','0737','0738','0739','0743','0744','0745','0746','0370','0371','0372','0373','0374','0375','0376','0377','0378','0379','0391','0392','0393','0394','0395','0396','0398','0870','0871','0872','0873','0874','0875','0876','0877','0878','0879','0691','0692','0881','0883','0886','0887','0888','0550','0551','0552','0553','0554','0555','0556','0557','0558','0559','0561','0562','0563','0564','0565','0566','0951','0952','0953','0954','0431','0432','0433','0434','0435','0436','0437','0438','0439','0440','0770','0771','0772','0773','0774','0775','0776','0777','0778','0779','0851','0852','0853','0854','0855','0856','0857','0858','0859','029','0910','0911','0912','0913','0914','0915','0916','0917','0919','0971','0972','0973','0974','0975','0976','0977','0890','0898','0899','0891','0892','0893');
        $storeDao=\DAO\StoreModel::getInstance();
        // $memberDao = \DAO\MemberModel::getInstance();
        $res =$storeDao->getAll();
        $drawTableDao=\DAO\Draw\DrawTableModel::getInstance();
        $drawTableDatas=$drawTableDao->getAll();
        for($i=0;$i<1000000;$i++){
            $memberId=50000+$i;
            $re=array_rand($res);
            $reDraw=array_rand($drawTableDatas);
            $storeCityCode=array_rand($cityCodes);
            $storeCityCode=$cityCodes[$storeCityCode];
            $temDrawData=$drawTableDatas[$reDraw];
            while(!$temDrawData['storeName']){
                $reDraw=array_rand($drawTableDatas);
                $temDrawData=$drawTableDatas[$reDraw];
            }
            if(!empty($res[$re])){
                $data=$res[$re];
                $data['store_id']=$memberId;
                $data['store_name']=$temDrawData['storeName'];
                $data['member_id']=$memberId;
                $data['store_description']=$temDrawData['storeAddress'].$temDrawData['storeName'];
                $data['store_address']=$temDrawData['storeAddress'];
                $data['store_zip']=$temDrawData['storeTelephone'];
                $data['store_state']=ApiConst::one;
                $data['live_store_name']=$temDrawData['storeName'];
                $data['live_store_address']=$temDrawData['storeAddress'];
                $data['store_longitude']=$temDrawData['positionX']/100000;
                $data['store_citycode']=$storeCityCode;
                $data['store_latitude']=$temDrawData['positionY']/100000;
                $storeDao->add($data);
                echo '增加数据'.$i.'条member_id 是:'.$memberId."\n";
            }
        }
    }

    public function updateStoreTotalDeposit(){
        \DAO\StoreModel::getInstance()->updateStoreDeposit();
    }

    /**
     * 待办事务通知
     */
    public function pendingItemsInform() {
        $storePaymentDao = \DAO\Store\StorePaymentModel::getInstance();
        $weiCount = $storePaymentDao->getStorePaymentCount(array('payment_type'=>0,'status'=>0));
        $storeRegisterDao = \DAO\Store\QmStoreRegisterModel::getInstance();
        $storeCount = $storeRegisterDao->getWaitCheckCount(array('state'=>0));
        $settingDAO = \DAO\SettingModel::getInstance();
        $phone = $settingDAO->getListCache(array('pending_items_inform_tel'))['pending_items_inform_tel'];
        \DAO\ShortMessageModel::getInstance()->sendMessageSmsForPlatform($phone,'storeWaitCheck',array('storeCount'=>$storeCount,'weiCount'=>$weiCount));
    }

    /**
     * 试用快到期通知
     */
    public function tryExpireInform() {
        $storeList = \DAO\StoreModel::getInstance()->getTryExpireStore();
        if($storeList) {
            foreach ($storeList as $store) {
                if( TIMESTAMP+9*24*3600<$store['store_end_time'] and  $store['store_end_time'] <= TIMESTAMP+10*24*3600) {
                    $limitday = 10;
                }elseif (TIMESTAMP+4*24*3600<$store['store_end_time'] and  $store['store_end_time'] <= TIMESTAMP+5*24*3600) {
                    $limitday = 5;
                }else{
                    $limitday = 3;
                }
                \DAO\ShortMessageModel::getInstance()->sendMessageSmsForPlatform($store['store_phone'],'tryExpire',array('storename'=>$store['store_name'],'limitday'=>$limitday));
            }
        }
    }
    /**
     * 签约分类快到期通知
     */
    public function signedClassExpireInform() {
        $classList = \DAO\QmStoreClassModel::getInstance()->selectByWhere(array('is_charged'=>1,'deadline'=>array('between',TIMESTAMP+2*24*3600+1,TIMESTAMP+3*24*3600),'class_style'=>2),'deadline,store_id');
        if($classList) {
            $storeIds = array_column($classList,'store_id');
            $storeFullList = \DAO\StoreModel::getInstance()->getStoreFullList(array('store_id'=>array('in',$storeIds)),'contract_time,store_id,store_phone,store_name');
            $list = \Our\Common::intergrateOneToOne($classList,$storeFullList,'store_id','store_id');
            foreach ($list as $v) {
                $deadline = $v['deadline'];
                $contarct_time = $v['contract_time'];
                if($deadline<$contarct_time){
                    $maxSignEndTime =  mktime(0,0,0,date('m',$contarct_time),1,date('Y',$contarct_time))-1;
                    if($maxSignEndTime==$deadline){
                        continue;
                    }
                    \DAO\ShortMessageModel::getInstance()->sendMessageSmsForPlatform($v['store_phone'],'signClassExpire',array('storename'=>$v['store_name']));
                }
            }
        }
    }

    /**
     * 试用期店铺引流人数统计
     */
    public function drainageAmountStatistics() {
        $orderDao = \DAO\Order\OrderGoodsModel::getInstance(\Our\DbNameConst::masterDBConnectName);
        $pageBegin = \Our\PageConst::taskPageBegin;
        $storeDao = \DAO\FavoritesStoreModel::getInstance();
        $storeDrainageAmountDao = \DAO\Store\StoreDrainageAmountModel::getInstance();
        while (true) {
            // -\Our\ApiConst::oneDaySecond 防止试用期最后一天的引流人数没统计到
            $stores = $storeDao->getStoreAndFavoriteStore('count(han_favorites_store.favid) AS amount,han_store.store_id,han_favorites_store.store_id AS storeId',array('store_end_time'=>array('gt',TIMESTAMP-\Our\ApiConst::oneDaySecond)),array(),array($pageBegin,500),'storeId','LEFT');
            if(empty($stores)) {
                break;
            }
            $storeDrainageAmountDao->insertAllOrUpdate($stores);
            $pageBegin = ($pageBegin + 1) * 500;
        }
    }

    /**
     * 试用期的店铺考核
     */
    public function tryStoreExamine() {
        $storeDrainageAmountDao = \DAO\Store\StoreDrainageAmountModel::getInstance();
        $storeClassPayLogDao = \DAO\Store\StoreClassPayLogModel::getInstance();
        $storeUtil = \Store\StoreUtil::getInstance();
        $pageBegin = \Our\PageConst::taskPageBegin;
        while (true) {
            $stores = $storeDrainageAmountDao->getStoreAndDrainageAmount(array('han_store_full.store_end_time'=>array('between',TIMESTAMP-\Our\ApiConst::oneDaySecond,TIMESTAMP),'han_store_drainage_amount.gmt_examine'=>0),'han_store_full.store_citycode,han_store_full.member_id,han_store_full.contract_time,han_store_full.store_end_time,han_store_full.store_phone,han_store_drainage_amount.*',array($pageBegin,1000));
//            $stores = $storeDrainageAmountDao->getStoreAndDrainageAmount(array('han_store.store_end_time'=>array('between',0,1648209008),'han_store_drainage_amount.gmt_examine'=>0),'han_store.store_citycode,han_store.member_id,han_store_drainage_amount.*',array($pageBegin,1000));
            if(empty($stores)) {
                break;
            }
            foreach ($stores as $store) {
                if($store['amount'] >= 400) {
                    //自动免费续费 当前签约分类租金2个月
                    $storeUtil->calcChargeMoney(array('month'=>2,'store_end_time'=>$store['store_end_time'],'contract_time'=>$store['contract_time']));
                }elseif ($store['amount'] >= 300) {
                    //自动免费续费 当前签约分类租金1个月
                    $storeUtil->calcChargeMoney(array('month'=>1,'store_end_time'=>$store['store_end_time'],'contract_time'=>$store['contract_time']));
                }
//                elseif ($store['amount'] < 30) {
//                    //查看是否有签约分类续费记录
//                    $log = $storeClassPayLogDao->getStoreClassPayLog(array('store_id'=>$store['store_id'],'pay_state'=>1));
//                    if(empty($log)) {
//                        //店铺下架，下架理由为 试用期考核不合格 并且  发送短信
//                        $this->storeClose($store,\Our\NameConst::tryStoreExamineFail);
//                    }
//                }
                $storeDrainageAmountDao->editDrainage(array('store_id'=>$store['store_id']),array('gmt_examine'=>TIMESTAMP));
            }
            $pageBegin = ($pageBegin + 1) * 1000;
        }
    }

    /**
     * 店铺下架处理
     * @param $storeId
     * @param $reason 下架原因
     */
    public function storeClose($storeInfo, $reason) {
        $storeDAO = \DAO\StoreModel::getInstance();
        $memberDAO = \DAO\MemberModel::getInstance();
        $qmStoreClassDAO = \DAO\QmStoreClassModel::getInstance();
        $return = $storeDAO->save(array('store_state'=>\Our\ApiConst::zero,'store_close_info'=>$reason),array('store_id'=>$storeInfo['store_id']));
        if($return !== false) {
            $storeDAO->delStoreInfoCache($storeInfo['store_id']);
            $memberDAO->saveInfo(array('store_id'=>\Our\ApiConst::zero),$storeInfo['member_id']);
            \Business\Store\StoreServiceModel::getInstance()->deleteStoreAndStoreClassCacheByCitycode($storeInfo['store_citycode']);
            \DAO\QmStoreClassModel::getInstance()->delStoreSignClassesCache($storeInfo['store_citycode'],$storeInfo['store_id']);
            \DAO\FavoritesStoreModel::getInstance()->delMyFavoritesStoreByStoreId($storeInfo['store_id']);
            $list = $qmStoreClassDAO->selectByWhere(array('store_id'=>$storeInfo['store_id'],'is_charged'=>1),'distinct(gc_parent_id) as gcId');
            if($list) {
                foreach ($list as $v) {
                    $this->deleteQmStoreClassByGcParentId($v['gcId']);
                }
            }
        }
    }
    /**
     */
    private static $_instance = null;

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

        return self::$_instance;
    }



}
