Phalcon Framework 1.3.4

Phalcon\Cache\Exception: Cannot connect to Memcached server

/app/wwwroot/api/rrjk160-disease/app/Library/City.php (149)
#0Phalcon\Cache\Backend\Memcache->_connect()
#1Phalcon\Cache\Backend\Memcache->save(Joy\Library\City\getCities, Array(2000), 600)
<?php
namespace Joy\Library;
 
use Joy\Api\AreaService;
use Joy\Library\Tools;
use Joy\Library\Object;
use Joy\Library\Filter;
use Joy\Api\DisearService;
 
/*
 * 提供当前城市检测、城市列表
 */
 
/**
 * 初始化当前城市、城市列表选择
 *
 * @author Liucong <liucong@91160.com>
 */
class City {
 
    /**
     * 检查子站是否开通,未开通子站默认跳转到深圳站
     * return void
     */
    public function checkSubDomain($ip) {
        //如果为91160.com,301跳转到www.rrjk160.com
        if (!WEBAPI_FROM) {
            Tools::redirectCode('www' . BASE_DOMAIN, 301);
        }
 
        //域名白名单
//        $whiteList = array(
//            'www', //主站域名
//            'doctor', //医生专题
//        );
        //判断子域名是否合法    
        $city_code_arr = $this->getCities();
 
        //如果(子域名不在域名白名单&&非城市子站)显示404错误
//        if (!(in_array(WEBAPI_FROM, $whiteList) || isset($city_code_arr[WEBAPI_FROM]))) {
//            Tools::redirectCode($this->url->get(['for' => 'unfind']), 404);
//            header('Location: http://ill.91160.com/404.html');
//        }
 
        //设置用户默认访问城市
        $cityCode = 'sz';
        if (isset($city_code_arr[WEBAPI_FROM])) {
            $cityCode = WEBAPI_FROM;
        } else {
            //存在cookie的情况
            $cookieCity = strtolower($_COOKIE['ip_city']);
            //初始化化,根据IP  自动获取城市,并设置cookie 
            if (!$cookieCity) {
                //根据IP 自动获取城市代号
                $cookieCity = $this->getCityInfoFromIp($ip);
            }
            //在域名白名单 才设置子域名
            if (isset($city_code_arr[$cookieCity])) {
                $cityCode = $cookieCity;
            }
        }
 
        define('CITY_ID', $city_code_arr[$cityCode]['area_id']);
        define('CITY_NAME', $city_code_arr[$cityCode]['area_name']);
        define('CITY_CODE', $cityCode);
        setcookie('ip_city', $cityCode, time() + 86400 * 30 * 12, '/', BASE_DOMAIN);
 
        //设置子域名默认控制器
//        $defaultController = array(
//            'www' => 'home', //整站首页
//            'doctor' => 'doctor', //医生专题
//        );
//        if (isset($defaultController[WEBAPI_FROM]) && empty($_GET['c'])) {
//            $_GET['c'] = $defaultController[WEBAPI_FROM];
//        }
 
        return true;
    }
    
    /**
     * 获取城市
    * @Title: getCitys 
    * @Description: 获取城市
    * @param     
    * @return array
     */
//    public function getCitys(){
//        //搜索医院获取城市
//        $city_code_arr =$this->getCities();
//         
//        $sort = array('ABCDE','FGHJ','KLMNP','QRSTW','XYZ');
//        $count = count($sort);
//        foreach ($city_code_arr as $k=>$v){
//            $newcity[$v['i_key']][$k] = $v;
//        }
//    
//        ksort($newcity);
//        $countcity = count($city_code_arr);
//        foreach ($newcity as $k=>$v){
//            if($v['hk']){
//                $anewcity[$count]['gat']['hk'] = $v['hk'];
//                unset($v['hk']);
//            }
//            for($i=0;$i<=$count-1;$i++){
//                if($k && strpos($sort[$i], $k)!==false){
//                    $anewcity[$i][$k] = $v;
//                }
//            }
//    
//        }
//        //$this->view->newcity = $cityData['cityCodeArr'];
//        return $anewcity;
//    }
    /**
     * 获取热门城市
    * @Title: getHotCitys 
    * @Description: 获取热门城市
    * @param     
    * @return array
     */
    public function getHotCitys(){
        $disCity = new DisearService();
        $hotCity = $disCity->getHotCity();
        return $hotCity;
    }
    
    private function getCities() {
        $cache_key = __CLASS__ . '\\' . __FUNCTION__;
        $cache = \Joy::$di->get('cache');
//        $city_code_arr = Object::ToArray($cache->get($cache_key));
        if (!$city_code_arr) {
            $args = array(
                'area_level' => 3,
                'is_show' => 1
            );
            $AreaService = new AreaService();
            $cityData = $AreaService->areaFindList($args);
            $city_code_arr = array();
            if (isset($cityData['data']) && $cityData['data']) {
                foreach ($cityData['data'] as $val) {
                    $cityCode = strtolower($val['area_code']);
                    $city_code_arr[$cityCode] = array(
                        'area_id' => $val['area_id'],
                        'area_name' => $val['area_name'],
                        'area_code' => $cityCode,
                        'i_key' => strtoupper($val['i_key'])
                    );
                }
                $cache->save($cache_key, $city_code_arr, 600);
            }
        }
        return $city_code_arr;
    }
    
    /**
     * 根据ip地址,自动获取对应城市信息cityCode 或者对应城市信息
     * 
     * @param string $ip 
     * @return string
     */
    private function getCityInfoFromIp($ip) {
 
        //根据IP自动获取 对应城市数据
        $url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=' . $ip;
        //设置请求IP 获取IP对应省份城市信息;
        $data = Tools::callCurl($url, array(), 'json', 'utf-8', 'post', 1);
 
        //设置返回 城市代号 默认返回sz
        if ($data) {
            //格式化接口地址数据
            $result = json_decode($data, true);
            //获取所有地区基础数据,有memcache缓存
            $city_code_arr = $this->getCities();
 
            if ($result['country'] != '中国') {
                return '';
            }
 
            foreach ($city_code_arr as $val) {
                if ($result['city'] == $val['area_name']) {
                    $infos = $val;
                }
            }
        }
        return $infos['area_code'];
        //返回   
    }
 
    /**
     * 
     * @param string $cookieCity 城市代号
     * @return array 返回
     */
    private function getCityInfoByCookie($cookieCity) {
        //获取所有地区基础数据,有memcache缓存
        $city_code_arr = $this->getCities();
 
        if (isset($city_code_arr[$cookieCity])) {
            return $city_code_arr[$cookieCity];
        }
 
        return array();
    }
    
    /**
     * 设置城市
     * 
     * @param string $cityCode
     */
//    private function setCityCode($cityCode) {
//        $cityCode = strtolower($cityCode);
//        //判断子域名是否合法    
//        $city_code_arr = $this->getCities();
//        if (isset($city_code_arr[$cityCode])) {
//            $_COOKIE['ip_city'] = $cityCode;
//            setcookie('ip_city', $cityCode, time() + 86400 * 30 * 12, '/', BASE_DOMAIN);
//        }
//    }
 
}
#2Joy\Library\City->getCities()
<?php
namespace Joy\Library;
 
use Joy\Api\AreaService;
use Joy\Library\Tools;
use Joy\Library\Object;
use Joy\Library\Filter;
use Joy\Api\DisearService;
 
/*
 * 提供当前城市检测、城市列表
 */
 
/**
 * 初始化当前城市、城市列表选择
 *
 * @author Liucong <liucong@91160.com>
 */
class City {
 
    /**
     * 检查子站是否开通,未开通子站默认跳转到深圳站
     * return void
     */
    public function checkSubDomain($ip) {
        //如果为91160.com,301跳转到www.rrjk160.com
        if (!WEBAPI_FROM) {
            Tools::redirectCode('www' . BASE_DOMAIN, 301);
        }
 
        //域名白名单
//        $whiteList = array(
//            'www', //主站域名
//            'doctor', //医生专题
//        );
        //判断子域名是否合法    
        $city_code_arr = $this->getCities();
 
        //如果(子域名不在域名白名单&&非城市子站)显示404错误
//        if (!(in_array(WEBAPI_FROM, $whiteList) || isset($city_code_arr[WEBAPI_FROM]))) {
//            Tools::redirectCode($this->url->get(['for' => 'unfind']), 404);
//            header('Location: http://ill.91160.com/404.html');
//        }
 
        //设置用户默认访问城市
        $cityCode = 'sz';
        if (isset($city_code_arr[WEBAPI_FROM])) {
            $cityCode = WEBAPI_FROM;
        } else {
            //存在cookie的情况
            $cookieCity = strtolower($_COOKIE['ip_city']);
            //初始化化,根据IP  自动获取城市,并设置cookie 
            if (!$cookieCity) {
                //根据IP 自动获取城市代号
                $cookieCity = $this->getCityInfoFromIp($ip);
            }
            //在域名白名单 才设置子域名
            if (isset($city_code_arr[$cookieCity])) {
                $cityCode = $cookieCity;
            }
        }
 
        define('CITY_ID', $city_code_arr[$cityCode]['area_id']);
        define('CITY_NAME', $city_code_arr[$cityCode]['area_name']);
        define('CITY_CODE', $cityCode);
        setcookie('ip_city', $cityCode, time() + 86400 * 30 * 12, '/', BASE_DOMAIN);
 
        //设置子域名默认控制器
//        $defaultController = array(
//            'www' => 'home', //整站首页
//            'doctor' => 'doctor', //医生专题
//        );
//        if (isset($defaultController[WEBAPI_FROM]) && empty($_GET['c'])) {
//            $_GET['c'] = $defaultController[WEBAPI_FROM];
//        }
 
        return true;
    }
    
    /**
     * 获取城市
    * @Title: getCitys 
    * @Description: 获取城市
    * @param     
    * @return array
     */
//    public function getCitys(){
//        //搜索医院获取城市
//        $city_code_arr =$this->getCities();
//         
//        $sort = array('ABCDE','FGHJ','KLMNP','QRSTW','XYZ');
//        $count = count($sort);
//        foreach ($city_code_arr as $k=>$v){
//            $newcity[$v['i_key']][$k] = $v;
//        }
//    
//        ksort($newcity);
//        $countcity = count($city_code_arr);
//        foreach ($newcity as $k=>$v){
//            if($v['hk']){
//                $anewcity[$count]['gat']['hk'] = $v['hk'];
//                unset($v['hk']);
//            }
//            for($i=0;$i<=$count-1;$i++){
//                if($k && strpos($sort[$i], $k)!==false){
//                    $anewcity[$i][$k] = $v;
//                }
//            }
//    
//        }
//        //$this->view->newcity = $cityData['cityCodeArr'];
//        return $anewcity;
//    }
    /**
     * 获取热门城市
    * @Title: getHotCitys 
    * @Description: 获取热门城市
    * @param     
    * @return array
     */
    public function getHotCitys(){
        $disCity = new DisearService();
        $hotCity = $disCity->getHotCity();
        return $hotCity;
    }
    
    private function getCities() {
        $cache_key = __CLASS__ . '\\' . __FUNCTION__;
        $cache = \Joy::$di->get('cache');
//        $city_code_arr = Object::ToArray($cache->get($cache_key));
        if (!$city_code_arr) {
            $args = array(
                'area_level' => 3,
                'is_show' => 1
            );
            $AreaService = new AreaService();
            $cityData = $AreaService->areaFindList($args);
            $city_code_arr = array();
            if (isset($cityData['data']) && $cityData['data']) {
                foreach ($cityData['data'] as $val) {
                    $cityCode = strtolower($val['area_code']);
                    $city_code_arr[$cityCode] = array(
                        'area_id' => $val['area_id'],
                        'area_name' => $val['area_name'],
                        'area_code' => $cityCode,
                        'i_key' => strtoupper($val['i_key'])
                    );
                }
                $cache->save($cache_key, $city_code_arr, 600);
            }
        }
        return $city_code_arr;
    }
    
    /**
     * 根据ip地址,自动获取对应城市信息cityCode 或者对应城市信息
     * 
     * @param string $ip 
     * @return string
     */
    private function getCityInfoFromIp($ip) {
 
        //根据IP自动获取 对应城市数据
        $url = 'http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=' . $ip;
        //设置请求IP 获取IP对应省份城市信息;
        $data = Tools::callCurl($url, array(), 'json', 'utf-8', 'post', 1);
 
        //设置返回 城市代号 默认返回sz
        if ($data) {
            //格式化接口地址数据
            $result = json_decode($data, true);
            //获取所有地区基础数据,有memcache缓存
            $city_code_arr = $this->getCities();
 
            if ($result['country'] != '中国') {
                return '';
            }
 
            foreach ($city_code_arr as $val) {
                if ($result['city'] == $val['area_name']) {
                    $infos = $val;
                }
            }
        }
        return $infos['area_code'];
        //返回   
    }
 
    /**
     * 
     * @param string $cookieCity 城市代号
     * @return array 返回
     */
    private function getCityInfoByCookie($cookieCity) {
        //获取所有地区基础数据,有memcache缓存
        $city_code_arr = $this->getCities();
 
        if (isset($city_code_arr[$cookieCity])) {
            return $city_code_arr[$cookieCity];
        }
 
        return array();
    }
    
    /**
     * 设置城市
     * 
     * @param string $cityCode
     */
//    private function setCityCode($cityCode) {
//        $cityCode = strtolower($cityCode);
//        //判断子域名是否合法    
//        $city_code_arr = $this->getCities();
//        if (isset($city_code_arr[$cityCode])) {
//            $_COOKIE['ip_city'] = $cityCode;
//            setcookie('ip_city', $cityCode, time() + 86400 * 30 * 12, '/', BASE_DOMAIN);
//        }
//    }
 
}
#3Joy\Library\City->checkSubDomain(216.73.217.174)
<?php
namespace Joy\Ill\Controllers;
 
use Phalcon\Http\Response;
use Joy\Web\HttpException;
use Joy\Library\City;
use Joy\Ill\Models\ConfigInc;
/**
 * 用于REST API的基类,用于输出错误
 *
 * @author dancebear
 *
 */
class Controller extends \Joy\Web\Controller {
 
    /**
     * 通用公共设置
     *
     * @var array
     */
    public $global_setting;
 
    /**
     * 初始化控制器
     * 解析出restful API的json数据并将其赋值给dispatcher以用作控制器动作的参数
     *
     * @return Ambigous <\Phalcon\Http\Response, \Phalcon\Http\ResponseInterface>
     */
    public function onConstruct() {
        $this->view->disable();
    }
 
    /**
     * 在这里我们校验了从json解析数据是否成功
     *
     * @see \Joy\Web\Controller::initialize()
     */
    public function initialize() {
        file_put_contents('debugg.log', json_encode($_COOKIE['UserName_datas']). '--888888--' . PHP_EOL, FILE_APPEND);
        $this->view->disableLevel(array(
            \Phalcon\Mvc\View::LEVEL_LAYOUT => true,
            \Phalcon\Mvc\View::LEVEL_MAIN_LAYOUT => true
        ));
        parent::initialize();
 
        // 检查子站是否开通,未开通子站默认跳转到深圳站
        $City = new City();
        $ip = $this->request->getClientAddress(true);
        $City->checkSubDomain($ip);
        //获取城市
//        $anewcity = $City->getCitys();
//        $this->view->anewcity = $anewcity;
 
        //获取热门城市
//        $hotCity = $City->getHotCitys();
//        $this->view->hotCity = $hotCity;
        $ill_Hot_Search = new ConfigInc();
        $ill_Search = $ill_Hot_Search->getList('hot_ill_search_tag');
        $this->view->ill_Search = explode(',', $ill_Search[0]['config_value']);
        //当前城市
//        $this->view->curCity = CITY_NAME;
        //当前的地址
        $HTTP_HOST = htmlspecialchars_decode($_SERVER['HTTP_HOST']);
        $HTTP_HOST = strip_tags($HTTP_HOST);
        $REQUEST_URI = htmlspecialchars_decode($_SERVER['REQUEST_URI']);
        $REQUEST_URI = strip_tags($REQUEST_URI);
        $this->view->location_url = ($_SERVER['HTTPS'] == "on" ? 'https://' : 'http://') . $HTTP_HOST.$REQUEST_URI;
        // 系统配置
        $global_setting =  \Joy::$config['globalSetting'];
        $global_setting['static_version'] = STATIC_VERSION;
        $global_setting['city_id'] =  CITY_ID ? CITY_ID : (empty($global_setting['city_id']) ? "5" : $global_setting['city_id']);
        $global_setting['city_name'] =  CITY_NAME ? CITY_NAME : (empty($global_setting['city_name']) ? "深圳" : $global_setting['city_name']);
        $global_setting['city_code'] =  CITY_CODE ? CITY_CODE : (empty($global_setting['city_code']) ? "sz" : $global_setting['city_code']);
        $this->view->global_setting = $this->global_setting = $global_setting;
    }
 
    /**
     * 返回一个错误
     *
     * @param integer $statuCode
     * @param string $message
     * @param array $messages
     * @return Response
     */
    public function sendError($statuCode, $message, $messages = [])
    {
        if (empty($messages))
        {
            $messages[] = $message;
            $message = null;
        }
        return $this->response->setStatusCode($statuCode, $message)->setJsonContent([
            "status" => $statuCode,
            "messages" => $messages
        ]);
    }
 
    /**
     * 捕获数据模型的错误
     *
     * @param \Phalcon\Mvc\ModelInterface $model
     * @return Response
     */
    public function catchModelMessage($model) {
        $messages = [];
        foreach ($model->getMessages() as $message) {
            $messages[] = $message->getMessage();
        }
        return $this->sendError(500, 'Data saving error', $messages);
    }
 
    /**
     * 校验用户权限,根据控制器名和动作名来校验用户的权限
     * $accessToken系统根据控制器名和动作名来自动生成
     * ```
     * $accessToken = substr(md5($module . $controller . $action), 0, 6);
     * ```
     * @see \Joy\Web\Controller::beforeExecuteRoute()
     * @see \Joy\Web\Controller::checkAccess()
     */
    public function checkAccess($accessToken) {
        return true;
    }
 
    public function beforeExecuteRoute($dispatcher) {
 
    }
}
#4Joy\Ill\Controllers\Controller->initialize()
<?php
namespace Joy\Ill\Controllers;
 
use Joy\Api\AdvertService;
use Joy\Api\CommentService;
use Joy\Api\DepService;
use Joy\Api\DoctorService;
use Joy\Api\IllService;
use Joy\Api\InquiryService;
use Joy\Api\UnitService;
use Joy\Ill\Models\AdList;
use Joy\Ill\Models\LinkList;
use Joy\Ill\Models\NewsArticle;
use Joy\Library\Date;
use Joy\Library\Images;
use Joy\Library\String;
use Joy\Library\Tools;
 
/**
 * Created by PhpStorm.
 * User: liuzhiwei
 * Date: 2016/9/14
 * Time: 11:47
 */
class ConsultController extends GeneralController
{
    /**
     * 广告位ID
     * @var array
     */
    public $ad_location_id = [
        'indexFocus_ads' => 89,  //web端-咨询频道首页-焦点图
        'indexRecomdoctor_ads' => 90, //web端-咨询频道首页-右侧推荐医生
        'indexMidcommon_ads' => 91,  //web端-咨询频道首页-中通广告图
        'indexRightdown_ads' => 92,  //web端-咨询频道首页-右下角广告图
        'TelconsultRecomdoctor_ads' => 93, //web端-咨询频道电话咨询医生列表页-右侧推荐医生
        'imgtextRecomdoctor_ads' => 94,  //web端-咨询频道图文咨询医生列表页-右侧推荐医生
        'pridoctorRecomdoctor_ads' => 95, //web端-咨询频道私人医生列表页-右侧推荐医生
        'indexVideoconsult_ads' => 101, //web端-咨询频道首页-视频咨询广告图(右上角广告)
    ];
 
    /**
     * 友情链接ID
     * @var int
     */
    public $link_location_id = 7;
 
    /**
     * @var array 医院级别
     */
    public static $unit_level = [
        1 => '三级甲等', //A,B
        2 => '三级', //C,D,L
        3 => '二级', //E,F,G,M
        4 => '一级', //H,I,J
        5 => '其他', //K
    ];
 
    /**
     * @var array 医生职称
     */
    public static $doctor_zc = [
        1 => '主任医师',
        2 => '副主任医师',
        3 => '主治医师',
        4 => '医师'
    ];
 
    /**
     * @var array 医生排序
     */
    public static $doc_sort = [
        1 => '综合排序',
        2 => '价格',
        3 => '咨询量',
        4 => '回复率',
        5 => '好评率',
    ];
 
    /**
     * 星级对应分数
     *
     * [半星|一星|一星半 ... 五星 => [分值区间]]
     * 星级显示规则如下:
     * 0分  0星
     * 0分<半星<=1分
     * 1分<1星≤2分
     * 2分<1星半≤3分
     * 3分<2星≤4分
     * 4分<2星半≤5分
     * 5分<3星≤6分
     * 6分<3星半≤7分
     * 7分<4星≤8分
     * 8分<4星半≤9分
     * 9分<5星≤10分
     *
     * @var array
     */
    protected $starInterval = [
        '0.5' => [0, 1],
        '1'   => [1, 2],
        '1.5' => [2, 3],
        '2'   => [3, 4],
        '2.5' => [4, 5],
        '3'   => [5, 6],
        '3.5' => [6, 7],
        '4'   => [7, 8],
        '4.5' => [8, 9],
        '5'   => [9, 10],
    ];
 
 
    /**
     * 初始化参数
     */
    public function initialize()
    {
        parent::initialize();
        $config = \Joy::$config['location_id'];
        $this->ad_location_id = array_merge($this->ad_location_id, (array)$config['ad_location_id']);
        $config['ad_location_id'] && $this->link_location_id = $config['link_location_id'];
 
        $this->view->consult_askdetail_url = 'http://www.rrjk160.com/doctors/askdetail/docid-'; //医生咨询详情页
        $this->view->consult_dianhua_url = 'http://www.rrjk160.com/doctors/dianhua/docid-'; //医生电话咨询页
        $this->view->consult_tuwen_url = 'http://www.rrjk160.com/doctors/ask/docid-'; //医生图文咨询页
        $this->view->doctors_buy_url = 'http://www.rrjk160.com/doctors/buy/docid-'; //医生私人医生页
        $this->view->doctors_index_url = 'http://www.rrjk160.com/doctors/index/docid-'; //医生主页
 
        //医生默认头像
        $this->view->doctor_default_img = $this->global_setting['static_url'] . 'images/doctor.jpg';
 
    }
 
    /**
     * 咨询频道首页
     */
    public function indexAction()
    {
        
        //一级公共科室
        $pubCatList = self::getPubCatList(['parentid' => 0]);
        $this->view->pubCatList = $pubCatList;
 
        //推荐医生
        $this->getHotDoctors();
 
        //最新回复
        $this->getLastRepDoctors();
 
        //经典咨询
        $this->getGoodAsks();
 
        $advert = new AdvertService();
 
        //web端-咨询频道首页-焦点图:广告后台配置
        $focus_ads = $advert->get_adlist_data($this->ad_location_id['indexFocus_ads']);
        $this->view->indexFocus_ads = $focus_ads[$this->ad_location_id['indexFocus_ads']];
 
        //web端-咨询频道首页-中通广告图:广告后台配置
        $midcommon_ads = $advert->get_adlist_data($this->ad_location_id['indexMidcommon_ads']);
        $this->view->indexMidcommon_ads = $midcommon_ads[$this->ad_location_id['indexMidcommon_ads']][0];
 
        //web端-咨询频道首页-视频咨询广告图:广告后台配置
        $video_ad = $advert->get_adlist_data($this->ad_location_id['indexVideoconsult_ads']);
        $this->view->indexVideoconsult_ads = $video_ad[$this->ad_location_id['indexVideoconsult_ads']][0];
 
        //web端-咨询频道首页-右下角广告图:广告后台配置
        $rightdown_ads = $advert->get_adlist_data($this->ad_location_id['indexRightdown_ads']);
        $this->view->indexRightdown_ads = $rightdown_ads[$this->ad_location_id['indexRightdown_ads']][0];
 
        //获取友情连接
        $linkList = (new LinkList())->getList($this->link_location_id);
        $this->view->linklist = $linkList;
 
        $this->seo['title'] = '电话咨询_图文咨询_私人医生_健康问题在线咨询专家医生_健康160挂号网';
        $this->seo['keywords'] = '电话咨询,图文咨询,私人医生,问医生,咨询医生,健康问答';
        $this->seo['description'] = '健康160挂号网咨询频道是全国最大的医生在线健康问答咨询平台.来自全国数十万名专家医生为您解答任何健康问题,可以通过电话、图文等多种方式与医生进行一对一咨询!';
        $this->view->seo = $this->seo;
        $this->view->pagehover = 'ask';
    }
 
    /**
     * 咨询首页ajax请求
     */
    public function consultAjaxAction()
    {
 
        $ask_type = $this->request->get('asktype', 'int'); //医生类型
        $catid = $this->request->get('catid', 'int');//一级公共科室
        if ($catid >= 0) {
            //二级公共科室
            $chlid_catids_tmp = self::getPubCatList(['parentid' => $catid]);
            $chlid_catids = array_column($chlid_catids_tmp, 'catid');
 
            $args['cat_id'] = $chlid_catids;
        }
 
        $page = 1;
        $pageSize = 20;
 
        switch ($ask_type) {
            case 1: //电话
                $args['type'] = 'ask_tel';
                $args['a.is_active'] = 1;
                $args['a.auth_status'] = 1;
                $sort_map = ['a.ask_tel_composite' => 'desc'];
                $ask_price = 'ask_tel_price';
                $price_unit = '元/分钟';
                $consult_tmp_url = $this->view->consult_dianhua_url;
                $title = '电话咨询';
                break;
            case 2: //图文
                $args['type'] = 'ask';
                $sort_map = ['ask_composite' => 'desc'];
                $ask_price = 'ask_price';
                $price_unit = '元';
                $consult_tmp_url = $this->view->consult_tuwen_url;
                $title = '图文咨询';
                break;
            case 3: //私人
                $args['type'] = 'vip';
                $sort_map = ['vip_composite' => 'desc'];
                $ask_price = 'vip_min_price';
                $price_unit = '元起';
                $consult_tmp_url = $this->view->doctors_buy_url;
                $title = '私人医生';
                break;
            default:
                break;
        }
 
        //根据条件查询咨询医生
        if ($ask_type == 1) {
            $consult_doctors = InquiryService::findJoinDoctor($args, $sort_map, ['*'], $page, $pageSize);
        } else {
            $consult_doctors = InquiryService::getDoctorList($args, $sort_map, [], $page, $pageSize);
        }
        if ($consult_doctors) {
            if ($ask_type == 1) {
                $tmpArr = $consult_doctors['list'];
            }else {
                $tmpArr = $consult_doctors['rows'];
            }
            //随机4值
            if (count($tmpArr) < 4){
                $consult_doctors = $tmpArr;
            }else {
                $key = array_rand($tmpArr, 4);
                $consult_doctors = [
                    0 => $tmpArr[$key[0]],
                    1 => $tmpArr[$key[1]],
                    2 => $tmpArr[$key[2]],
                    3 => $tmpArr[$key[3]]
                ];
            }
            foreach ($consult_doctors as $k => $v) {
 
                $consult_url = $consult_tmp_url . $v['doctor_id'].'.html'; //医生头像和姓名,咨询按钮跳转url
 
                $consult_doctors[$k]['good_at'] = implode(',', self::getDocDiseaseTag($v['doctor_id']));
                //若无标签则抓取擅长疾病介绍(文本)
                if (empty($consult_doctors[$k]['good_at'])) {
                    $consult_doctors[$k]['good_at'] = self::getDocExpert($v['doctor_id']);
                }
                //医生擅长文字处理
                $consult_doctors[$k]['good_at'] = $consult_doctors[$k]['good_at'] ? String::subString($consult_doctors[$k]['good_at'], 10)  : '暂无';
                // 评分
                $consult_doctors[$k]['overall_star'] = $this->star($v['comment_score']);
                //字符截取
                $depName = $consult_doctors[$k]['dep_name'] ? $consult_doctors[$k]['dep_name'] : $consult_doctors[$k]['cat_name'];
                $consult_doctors[$k]['short_dep_name'] = String::subString($depName,4);
                $consult_doctors[$k]['short_doctor_name'] = String::subString($consult_doctors[$k]['doctor_name'],5);
                $consult_doctors[$k]['short_unit_name'] = String::subString($consult_doctors[$k]['unit_name'],6);
 
                $consult_doctors[$k]['img'] = $consult_doctors[$k]['icon'] ? $consult_doctors[$k]['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
                $consult_doctors[$k]['zc'] = self::getDoctorZc()[$consult_doctors[$k]['zcid']];
                //统一价格字段
                $consult_doctors[$k]['price'] = $consult_doctors[$k][$ask_price];
                if($ask_type == 1){
                    //统一价格字段
                    $consult_doctors[$k]['price'] = $consult_doctors[$k]['ask_tel_total_price'];
                    $price_unit = '元/'.$consult_doctors[$k]['ask_tel_min_buy'].'分钟起';
                }
 
                //样式处理
                $mr50 = ($k % 2 == 0) ? 'mr50' : '';
                $overall_star = $consult_doctors[$k]['overall_star'] * 20;
                $html .= <<<EOT
                    <div class="l-doc-item fl {$mr50}">
                    <div class="s-pic fl mb75">
                    <a href="{$consult_url}" target="_blank" onclick="setTongji('click', '咨询频道首页-{$title}列表-{$consult_doctors[$k]['doctor_name']}医生-点击量', 'img', this)" title="{$consult_doctors[$k]['doctor_name']}">
                    <img width="110" height="110" src="{$consult_doctors[$k]['img']}" onerror="nothumb('{$this->view->doctor_default_img}', this)" /></a>
                    <p class="mt15 fs12 typo-sgray tc">
                    <span>{$consult_doctors[$k]['price']}</span>{$price_unit}</p>
                    </div><h3 class="inblo lh fn">
                    <a href="{$consult_url}" class="fs14 typo-black" target="_blank" onclick="setTongji('click', '咨询频道首页-{$title}列表-{$consult_doctors[$k]['doctor_name']}医生-点击量', 'a', this)" title="{$consult_doctors[$k]['doctor_name']}">{$consult_doctors[$k]['short_doctor_name']}</a>
                    </h3><strong class="ml10 fs14 typo-gray fn">{$consult_doctors[$k]['zc']}</strong>
                    <a href="{$consult_url}" target="_blank" class="typo-blue fs14 fr" onclick="setTongji('click', '咨询频道首页-{$title}列表-{$consult_doctors[$k]['doctor_name']}医生-点击量', 'a', this)" title="{$consult_doctors[$k]['doctor_name']}">咨询</a>
                    <p class="typo-gray mt20 lh"><span class="mr30 dep_name" title="{$depName}">
                    <i class="iconfont typo-qgray mr10">&#xe60b;</i>{$consult_doctors[$k]['short_dep_name']}</span>
                    <span title="{$consult_doctors[$k]['unit_name']}" class="unit_name">
                    <i class="iconfont typo-qgray mr10">&#xe600;</i>{$consult_doctors[$k]['short_unit_name']}</span></p>
                    <p class="lh75 mt15 fs14"><em class="typo-qgray">擅长:</em>{$consult_doctors[$k]['good_at']}</p>
                    <div class="zs mt15 mr10">医生点评总分:<i class="typo-orange ml10">{$consult_doctors[$k]['comment_score']}</i></div>
                    <div class="lh fs20 typo-qgray mt5">
                    <div class="lh fs20 typo-qgray mt10 inblo score" star="{$consult_doctors[$k]['comment_score']}">
                    <i class="score-c" style="width:{$overall_star}%"></i></div></div>
                    </div>
EOT;
 
            }
 
            $this->ajaxReturn($html);
        }
 
        $this->ajaxReturn('', -1, '记录为空');
    }
 
    /**
     * 电话咨询
     */
    public function telconsultAction()
    {
        $this->view->doctorZc = $doctorZc = $this->request->get('doctorZc', 'int', -1);
        $this->view->unitLevel = $unitLevel = $this->request->get('unitLevel', 'int', -1);
        $this->view->pubCat = $pubCat = $this->request->get('pubCat', 'int', -1);
        $this->view->child_pubCat = $child_pubCat = $this->request->get('child_pubCat', 'int', 0);
        $this->view->docSort = $docSort = $this->request->get('docSort', 'int', 1);
        $page = $this->request->get('page', 'int', 1);
        $pageSize = 10;
 
        $args['type'] = 'ask_tel';
        $args['a.is_active'] = 1;
        $args['a.auth_status'] = 1;
        $doctorZc > 0 && $args['a.zcid'] = $doctorZc;
        $unitLevel > 0 && $args['a.unit_level'] = $this->getUnitLevel($unitLevel);
        $pubCat > 0 && ($args['a.cat_id'] = $child_pubCat > 0 ? $child_pubCat : array_column(self::getPubCatList(['parentid'=>$pubCat]), 'catid'));
 
        switch ($docSort) {
            case 1: //综合
                $sort_map = ['a.ask_tel_composite' => 'desc'];
                break;
            case 2: //价格
                $sort_map = ['a.ask_tel_total_price' => 'asc', 'a.ask_tel_composite' => 'desc'];
                break;
            case 3: //咨询量
                $sort_map = ['a.history_ask_total' => 'desc', 'a.ask_tel_composite' => 'desc'];
                break;
            case 4: //回复率
                $sort_map = ['a.history_ask_reply_total_rate' => 'desc', 'a.ask_tel_composite' => 'desc'];
                break;
            case 5: //好评率
                $sort_map = ['a.comment_score'=>'desc', 'a.ask_tel_composite' => 'desc'];
                break;
        }
 
        //根据条件查询咨询医生
        $tmpArr = InquiryService::findJoinDoctor($args, $sort_map, ['*'], $page, $pageSize);
        $consult_doctors = $tmpArr['list'];
        foreach ($consult_doctors as $k => $v) {
            $consult_url = ''; //医生头像和姓名,咨询按钮跳转url
 
            $consult_doctors[$k]['good_at'] = self::getDocDiseaseTag($v['doctor_id'], 1, 7, 30);
 
            //疾病标签处理
            $str = '';
            if($consult_doctors[$k]['good_at']){
                foreach ($consult_doctors[$k]['good_at'] as $k2 => $v2) {
                    $str .= '<span class="zx">' . $v2 . '</span>';
                }
            }
            $consult_doctors[$k]['good_at'] = $str ? $str : '暂无';
 
            // 评分
            $consult_doctors[$k]['overall_star'] = $this->star($v['comment_score']);
 
            $consult_doctors[$k]['img'] = $consult_doctors[$k]['icon'] ? $consult_doctors[$k]['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
            $consult_doctors[$k]['zc'] = self::getDoctorZc()[$consult_doctors[$k]['zcid']];
            //统一价格字段
            $consult_doctors[$k]['price'] = $consult_doctors[$k]['ask_tel_total_price'];
            $consult_doctors[$k]['price_unit'] = $consult_doctors[$k]['ask_tel_min_buy'];
        }
        $this->view->consult_doctors = $consult_doctors;
 
        //处理分页
        if ($tmpArr['total'] > $pageSize)
        {
            $url = $this->url->get(['for' => 'consult_telconsult']);
            $url .= '?doctorZc=' . $doctorZc . '&unitLevel=' . $unitLevel . '&pubCat=' . $pubCat . '&docSort=' . $docSort . '&child_pubCat=' . $child_pubCat;
            $page = $this->pager($url . '&page=_num_', $tmpArr['total'], $page, $pageSize);
            $this->view->page = $page;
        }
 
        //基础数据
        $this->view->menuName = '电话咨询';
        $this->view->doctorZcs = self::getChildDoctorZc();
        $this->view->unitLevels = self::$unit_level;
        $this->view->pubCats = self::getPubCatList(['parentid' => 0]);
        $this->view->docSorts = self::$doc_sort;
        $pubCat > 0 && $this->view->childPubCats = self::getPubCatList(['parentid' => $pubCat]);
        //热门医生
        $this->getHotDoctors(1);
        //最新文章
        $this->getArticleList(10);
 
        //最新回复
        $this->getLastRepDoctors();
 
        $this->seo['title'] = '电话咨询医生_电话医生_与你的主治医生直接通话_健康160挂号网';
        $this->seo['keywords'] = '电话咨询医生,电话医生,与医生通话';
        $this->seo['description'] = '健康160挂号网咨询频道—电话咨询,为您提供电话咨询医生服务.通过直接便捷的电话交流方式进行疾病咨询与诊断,根据您的病情给到专业、及时的治疗预防建议.';
        $this->view->seo = $this->seo;
    }
 
    /**
     * 图文咨询
     */
    public function imgtextAction()
    {
        $this->view->doctorZc = $doctorZc = $this->request->get('doctorZc', 'int', -1);
        $this->view->unitLevel = $unitLevel = $this->request->get('unitLevel', 'int', -1);
        $this->view->pubCat = $pubCat = $this->request->get('pubCat', 'int', -1);
        $this->view->child_pubCat = $child_pubCat = $this->request->get('child_pubCat', 'int', 0);
        $this->view->docSort = $docSort = $this->request->get('docSort', 'int', 1);
        $page = $this->request->get('page', 'int', 1);
        $pageSize = 10;
 
        $args['type'] = 'ask';
        $doctorZc > 0 && $args['zcid'] = $doctorZc;
        $unitLevel > 0 && $args['unit_level'] = $this->getUnitLevel($unitLevel);
        $pubCat > 0 && ($args['cat_id'] = $child_pubCat > 0 ? $child_pubCat : array_column(self::getPubCatList(['parentid'=>$pubCat]), 'catid'));
 
        switch ($docSort) {
            case 1: //综合
                $sort_map = ['ask_composite' => 'desc'];
                break;
            case 2: //价格
                $sort_map = ['ask_price' => 'asc', 'ask_composite' => 'desc'];
                break;
            case 3: //咨询量
                $sort_map = ['history_ask_total' => 'desc', 'ask_composite' => 'desc'];
                break;
            case 4: //回复率
                $sort_map = ['history_ask_reply_total_rate' => 'desc', 'ask_composite' => 'desc'];
                break;
            case 5: //好评率
                $sort_map = ['comment_score' => 'desc', 'ask_composite' => 'desc'];
                break;
        }
 
        //根据条件查询咨询医生
        $tmpArr = InquiryService::getDoctorList($args, $sort_map, [], $page, $pageSize);
        $consult_doctors = $tmpArr['rows'];
        foreach ($consult_doctors as $k => $v) {
            $consult_url = ''; //医生头像和姓名,咨询按钮跳转url
 
            $consult_doctors[$k]['good_at'] = self::getDocDiseaseTag($v['doctor_id'], 1, 7, 30);
 
            //疾病标签处理
            $str = '';
            if($consult_doctors[$k]['good_at']){
                foreach ($consult_doctors[$k]['good_at'] as $k2 => $v2) {
                    $str .= '<span class="zx">' . $v2 . '</span>';
                }
            }
            $consult_doctors[$k]['good_at'] = $str ? $str : '暂无';
 
            // 评分
            $consult_doctors[$k]['overall_star'] = $this->star($v['comment_score']);
 
            $consult_doctors[$k]['img'] = $consult_doctors[$k]['icon'] ? $consult_doctors[$k]['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
            $consult_doctors[$k]['zc'] = self::getDoctorZc()[$consult_doctors[$k]['zcid']];
            //统一价格字段
            $consult_doctors[$k]['price'] = $consult_doctors[$k]['ask_price'];
        }
        $this->view->consult_doctors = $consult_doctors;
        //print_r($this->view->consult_doctors);
 
        //处理分页
        if ($tmpArr['total'] > $pageSize)
        {
            $url = $this->url->get(['for' => 'consult_imgtext']);
            $url .= '?doctorZc=' . $doctorZc . '&unitLevel=' . $unitLevel . '&pubCat=' . $pubCat . '&docSort=' . $docSort . '&child_pubCat=' . $child_pubCat;
            $page = $this->pager($url . '&page=_num_', $tmpArr['total'], $page, $pageSize);
            $this->view->page = $page;
        }
 
        //基础数据
        $this->view->menuName = '图文咨询';
        $this->view->doctorZcs = self::getChildDoctorZc();
        $this->view->unitLevels = self::$unit_level;
        $this->view->pubCats = self::getPubCatList(['parentid' => 0]);
        $this->view->docSorts = self::$doc_sort;
        $pubCat > 0 && $this->view->childPubCats = self::getPubCatList(['parentid' => $pubCat]);
        //热门医生
        $this->getHotDoctors(2);
        //最新文章
        $this->getArticleList(10);
        //最新回复
        $this->getLastRepDoctors();
 
        $this->seo['title'] = '图文咨询医生_健康160挂号网';
        $this->seo['keywords'] = '图文咨询医生';
        $this->seo['description'] = '健康160挂号网咨询频道—图文咨询,把您的健康问题通过图文的形式提交给医生,医生会在第一时间给您专业、及时的治疗预防建议.';
        $this->view->seo = $this->seo;
    }
 
 
    /**
     * 私人医生
     */
    public function pridoctorAction()
    {
        $this->view->doctorZc = $doctorZc = $this->request->get('doctorZc', 'int', -1);
        $this->view->unitLevel = $unitLevel = $this->request->get('unitLevel', 'int', -1);
        $this->view->pubCat = $pubCat = $this->request->get('pubCat', 'int', -1);
        $this->view->child_pubCat = $child_pubCat = $this->request->get('child_pubCat', 'int', 0);
        $this->view->docSort = $docSort = $this->request->get('docSort', 'int', 1);
        $page = $this->request->get('page', 'int', 1);
        $pageSize = 10;
 
        $args['type'] = 'vip';
        $doctorZc > 0 && $args['zcid'] = $doctorZc;
        $unitLevel > 0 && $args['unit_level'] = $this->getUnitLevel($unitLevel);
        $pubCat > 0 && ($args['cat_id'] = $child_pubCat > 0 ? $child_pubCat : array_column(self::getPubCatList(['parentid'=>$pubCat]), 'catid'));
 
        switch ($docSort) {
            case 1: //综合
                $sort_map = ['vip_composite' => 'desc'];
                break;
            case 2: //价格
                $sort_map = ['vip_min_price' => 'asc', 'vip_composite' => 'desc'];
                break;
            case 3: //咨询量
                $sort_map = ['history_ask_total' => 'desc', 'vip_composite' => 'desc'];
                break;
            case 4: //回复率
                $sort_map = ['vip_reply_rate' => 'desc', 'vip_composite' => 'desc'];
                break;
            case 5: //好评率
                $sort_map = ['comment_score' => 'desc', 'vip_composite' => 'desc'];
                break;
        }
 
        //根据条件查询咨询医生
        $tmpArr = InquiryService::getDoctorList($args, $sort_map, [], $page, $pageSize);
        $consult_doctors = $tmpArr['rows'];
        foreach ($consult_doctors as $k => $v) {
            $consult_url = ''; //医生头像和姓名,咨询按钮跳转url
 
            $consult_doctors[$k]['good_at'] = self::getDocDiseaseTag($v['doctor_id'], 1, 7, 30);
 
            //疾病标签处理
            $str = '';
            if($consult_doctors[$k]['good_at']){
                foreach ($consult_doctors[$k]['good_at'] as $k2 => $v2) {
                    $str .= '<span class="zx">' . $v2 . '</span>';
                }
            }
            $consult_doctors[$k]['good_at'] = $str ? $str : '暂无';
 
            // 评分
            $consult_doctors[$k]['overall_star'] = $this->star($v['comment_score']);
 
            $consult_doctors[$k]['img'] = $consult_doctors[$k]['icon'] ? $consult_doctors[$k]['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
            $consult_doctors[$k]['zc'] = self::getDoctorZc()[$consult_doctors[$k]['zcid']];
            //统一价格字段
            $consult_doctors[$k]['price'] = $consult_doctors[$k]['vip_min_price'];
        }
        $this->view->consult_doctors = $consult_doctors;
        //print_r($this->view->consult_doctors);
 
        //处理分页
        if ($tmpArr['total'] > $pageSize)
        {
            $url = $this->url->get(['for' => 'consult_pridoctor']);
            $url .= '?doctorZc=' . $doctorZc . '&unitLevel=' . $unitLevel . '&pubCat=' . $pubCat . '&docSort=' . $docSort . '&child_pubCat=' . $child_pubCat;
            $page = $this->pager($url . '&page=_num_', $tmpArr['total'], $page, $pageSize);
            $this->view->page = $page;
        }
 
        //基础数据
        $this->view->menuName = '私人医生';
        $this->view->doctorZcs = self::getChildDoctorZc();
        $this->view->unitLevels = self::$unit_level;
        $this->view->pubCats = self::getPubCatList(['parentid' => 0]);
        $this->view->docSorts = self::$doc_sort;
        $pubCat > 0 && $this->view->childPubCats = self::getPubCatList(['parentid' => $pubCat]);
        //热门医生
        $this->getHotDoctors(3);
        //最新文章
        $this->getArticleList(10);
        //最新回复
        $this->getLastRepDoctors();
 
        $this->seo['title'] = '私人医生_健康160挂号网';
        $this->seo['keywords'] = '私人医生';
        $this->seo['description'] = '健康160挂号网咨询频道—私人医生,为您提供包周或包月的咨询服务,在期间内您可以向医生发起不限次数的咨询,医生为您量身定制健康计划.';
        $this->view->seo = $this->seo;
    }
 
    /**
     * 右侧热门医生
     * @param int $ask_type
     */
    private function getHotDoctors($ask_type = 0)
    {
        switch ($ask_type) {
            case 1: //电话
                $args = ['type' => 'ask_tel','zcid'=>[1,2]];
                $sort_map = ['ask_tel_composite' => 'desc'];
                $location_id = $this->ad_location_id['TelconsultRecomdoctor_ads'];
                $consult_tmp_url = $this->view->consult_dianhua_url;
                break;
            case 2: //图文
                $args = ['type' => 'ask','zcid'=>[1,2]];
                $sort_map = ['ask_composite' => 'desc'];
                $location_id = $this->ad_location_id['imgtextRecomdoctor_ads'];
                $consult_tmp_url = $this->view->consult_tuwen_url;
                break;
            case 3: //私人
                $args = ['type' => 'vip','zcid'=>[1,2]];
                $sort_map = ['vip_composite' => 'desc'];
                $location_id = $this->ad_location_id['pridoctorRecomdoctor_ads'];
                $consult_tmp_url = $this->view->doctors_buy_url;
                break;
            default://首页 ,同时开通电话咨询和付费咨询,医生级别为主任医师或副主任医师
                $args = ['is_ask' => 1, 'is_ask_tel'=>1, 'zcid'=>[1,2]];
                $sort_map = ['doctor_composite' => 'desc'];
                $location_id = $this->ad_location_id['indexRecomdoctor_ads'];
                $consult_tmp_url = $this->view->doctors_index_url;
                break;
        }
 
 
        //优先从广告系统获取
        $ad_data_doctor = (new AdvertService())->get_adlist_data($location_id);
        $ad_doctor_list = $ad_data_doctor ? $ad_data_doctor[$location_id] : [];
        if($ad_doctor_list){
            $doctor_ids = array_column($ad_doctor_list, 'doctor_id');//医生id
 
            //获取医生履历表信息
            $doctorIds = implode(',', $doctor_ids);
            $docResumeInfo = InquiryService::getMultiPractices($doctorIds);
 
            //获取医生信息
            $doctors = (new DoctorService())->doctorsInIds($doctor_ids, null, true);
            //医生关联的科室
            $dep_names = (new DepService())->depDocsInDoctorIds($doctor_ids);
            $dep_names = array_column($dep_names,null, 'doctor_id');
 
            foreach($ad_doctor_list as $k=>$v){
                //先从doctor_statistic中获取医生信息
                $params = ['doctor_id' => intval($v['doctor_id'])];
                $consult_doctor_list = InquiryService::getDoctorList($params, [], [], 1, 1);
                if($consult_doctor_list['rows']){
                    $ad_doctor_list[$k] = array_merge($ad_doctor_list[$k], $consult_doctor_list['rows'][0]);
                    $ad_doctor_list[$k]['zc'] = self::getDoctorZc()[$ad_doctor_list[$k]['zcid']];
                }else{
                    //没有的话先获取履历表的,没有再获取基础数据信息
                    $ad_doctor_list[$k]['doctor_name'] = $docResumeInfo[$v['doctor_id']]['doctor_name'] ? $docResumeInfo[$v['doctor_id']]['doctor_name'] : $doctors[$v['doctor_id']]['doctor_name'];
                    $ad_doctor_list[$k]['unit_name'] = $docResumeInfo[$v['doctor_id']]['unit_name'] ? $docResumeInfo[$v['doctor_id']]['unit_name'] : $doctors[$v['doctor_id']]['unit_name'];
                    $ad_doctor_list[$k]['zcid'] = $docResumeInfo[$v['doctor_id']]['zc_id'] ? $docResumeInfo[$v['doctor_id']]['zc_id'] : $doctors[$v['doctor_id']]['zcid'];
                    $ad_doctor_list[$k]['icon'] = $docResumeInfo[$v['doctor_id']]['image'] ? $docResumeInfo[$v['doctor_id']]['image'] : $doctors[$v['doctor_id']]['image'];
                    $ad_doctor_list[$k]['dep_name'] = $docResumeInfo[$v['doctor_id']]['dep_name'] ? $docResumeInfo[$v['doctor_id']]['dep_name'] : $dep_names[$v['doctor_id']]['dep_name'];
                }
            }
        }
 
        $limits = 3 - count($ad_doctor_list);
        $consult_doctors = [];
        if ($limits > 0) {
            //根据条件查询咨询医生
            $tmp_doctors = InquiryService::getDoctorList($args, $sort_map, [], 1, 10);
            $tmp_doctors = $tmp_doctors['rows'];
            //随机值
            $rand_keys = array_rand($tmp_doctors, $limits);
            if(is_array($rand_keys)){
                foreach ($rand_keys as $v) {
                    $consult_doctors[] = $tmp_doctors[$v];
                }
            }else{
                $consult_doctors[] = $tmp_doctors[$rand_keys];
            }
        }
        $consult_doctors = array_merge($ad_doctor_list, $consult_doctors);
        foreach($consult_doctors as $k=>$v){
            //字符截取
            $consult_doctors[$k]['short_dep_name'] = String::subString($consult_doctors[$k]['dep_name'],4);
            $consult_doctors[$k]['short_doctor_name'] = String::subString($consult_doctors[$k]['doctor_name'],5);
            $consult_doctors[$k]['short_unit_name'] = String::subString($consult_doctors[$k]['unit_name'],6);
            $consult_doctors[$k]['zc'] = self::getDoctorZc()[$v['zcid']];
            $consult_doctors[$k]['img'] = $v['icon'] ? $v['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
            $consult_doctors[$k]['doc_url'] = $consult_tmp_url.$v['doctor_id'].'.html';
        }
 
 
        $this->view->hotDoctors = $consult_doctors;
    }
 
    /**
     * 右侧最新回复的医生
     */
    private function getLastRepDoctors()
    {
        //根据条件查询咨询医生
        $args = ['type' => 'ask'];
        $sort_map = ['history_ask_reply_total_rate' => 'desc'];
 
        $tmp_doctors = InquiryService::getDoctorList($args, $sort_map, [], 1, 3);
        $consult_doctors = $tmp_doctors['rows'];
 
        foreach ($consult_doctors as $k => $v) {
            $dep_name = $consult_doctors[$k]['dep_name'] ? $consult_doctors[$k]['dep_name'] : $consult_doctors[$k]['cat_name']; //没有科室用公共科室
            //字符截取
            $consult_doctors[$k]['short_dep_name'] = String::subString($dep_name,4);
            $consult_doctors[$k]['short_doctor_name'] = String::subString($consult_doctors[$k]['doctor_name'],5);
            $consult_doctors[$k]['short_unit_name'] = String::subString($consult_doctors[$k]['unit_name'],6);
 
            $consult_doctors[$k]['zc'] = self::getDoctorZc()[$v['zcid']];
            $consult_doctors[$k]['img'] = $v['icon'] ? $v['icon'] : $this->global_setting['static_url'] . 'images/doctor.jpg';
            $consult_doctors[$k]['ask_last_reply_time'] = strtotime($consult_doctors[$k]['ask_last_reply_time']) ? Date::friendlyDate(strtotime($consult_doctors[$k]['ask_last_reply_time'])) : '1年前';
        }
 
        $this->view->lastRepDoctors = $consult_doctors;
    }
 
    /**
     * 右侧最新文章
     * @access private
     * @param  int $num 显示条数
     * @return void
     */
    private function getArticleList($num = 6)
    {
        $article = new NewsArticle();
        $articleList = $article->getArticleList($num);
        $this->view->articleList = $articleList;
    }
 
    /**
     * 经典咨询
     */
    private function getGoodAsks()
    {
        $goodaskList = InquiryService::getGoodAskList();
 
        $doctor_ids = array_column($goodaskList, 'doctor_id'); //医生ID
        $dep_ids = array_column($goodaskList, 'dep_id');//科室id
        $unit_ids = array_column($goodaskList, 'unit_id');//医院id
 
        //获取医生详情,科室,医院
        $doctors = (new DoctorService())->doctorsInIds($doctor_ids, null, true);
        $dep_names = (new DepService())->depsInIds($dep_ids);
        $unit_names = (new UnitService())->unitsInIds($unit_ids);
 
        $dep_names = array_column($dep_names, null, 'dep_id');
        $unit_names = array_column($unit_names, null, 'unit_id');
 
        foreach ($goodaskList as $k => $v) {
 
            $goodaskList[$k]['doctor_name'] = empty($goodaskList[$k]['doctor_name']) ? $doctors[$v['doctor_id']]['doctor_name'] : $goodaskList[$k]['doctor_name'];
            $goodaskList[$k]['unit_name'] = empty($goodaskList[$k]['unit_name']) ? $unit_names[$v['unit_id']]['unit_name'] : $goodaskList[$k]['unit_name'];
            $goodaskList[$k]['dep_name'] = empty($goodaskList[$k]['dep_name']) ? $dep_names[$v['dep_id']]['dep_name'] : $goodaskList[$k]['dep_name'];
            $goodaskList[$k]['zc'] = empty($goodaskList[$k]['zc_name']) ? self::getDoctorZc()[$doctors[$v['doctor_id']]['zcid']] : $goodaskList[$k]['zc_name'];
            $goodaskList[$k]['time'] = date('Y-m-d', $goodaskList[$k]['add_time']);
            //处理中英文混排串的占位符计算
            $goodaskList[$k]['content'] = String::stringWidth($goodaskList[$k]['content'], 90);
 
            $width = mb_strwidth($goodaskList[$k]['doc_content'][0]['content']. 'utf-8');
            $goodaskList[$k]['doc_reply'] = $width > 100 ? String::stringWidth($goodaskList[$k]['doc_content'][0]['content'], 180) : $goodaskList[$k]['doc_content'][0]['content'].'<br/>'.String::stringWidth($goodaskList[$k]['doc_content'][1]['content'], 80);
 
            //隐藏手机号 136****5059
            $goodaskList[$k]['content'] = Tools::privateMobile($goodaskList[$k]['content']);
            $goodaskList[$k]['doc_reply'] = Tools::privateMobile($goodaskList[$k]['doc_reply']);
 
        }
 
        $this->view->goodaskList = $goodaskList;
    }
 
    /**
     * ajax请求获取公共科室
     */
    public function getPubCatsAction()
    {
        $catid = $this->request->get('catid', 'int');
 
        $GeneralController = new GeneralController();
        $GeneralController->shutDownCache = 0; //禁用手动关闭缓存
 
        $cacheKey = 'pubCats_' . md5($catid);
        $cacheRes = $GeneralController->getCache($cacheKey);
 
        if ($cacheRes) {
            $this->ajaxReturn(json_decode($cacheRes, true));
        } else {
            $res = (new DepService())->getDepListNoPage(['parentid' => $catid],[],['catid','catname']);
 
            if ($res) {
                $GeneralController->saveCache($cacheKey, json_encode($res));
                $this->ajaxReturn($res);
            }
            $this->ajaxReturn('', -1, '记录为空');
        }
    }
 
 
    /**
     * 获取医院级别
     * @param $level 级别
     * @return array
     */
    protected static function getUnitLevel($level)
    {
        $data = [];
        switch ($level) {
            case 1: //三级甲等(包含特级、三级甲等)
                $data = ['A', 'B'];
                break;
            case 2: //三级(包含三级乙三级丙等)
                $data = ['C', 'D', 'L'];
                break;
            case 3: //二级(二级甲乙丙等)
                $data = ['E', 'F', 'G', 'M'];
                break;
            case 4: //一级(一级甲乙丙等)
                $data = ['H', 'I', 'J'];
                break;
            case 5: //其他
                $data = ['K'];
                break;
        }
 
        return $data;
    }
 
    /**
     * 获取公共科室
     * @param array $args
     * @param string $cacheKey
     * @return array|bool|null
     */
    protected static function getPubCatList($args = [], $cacheKey = 'pubcat_')
    {
        $GeneralController = new GeneralController();
        $GeneralController->shutDownCache = 0; //禁用手动关闭缓存
 
        $cacheKey = $cacheKey . md5(json_encode($args));
        $cacheRes = $GeneralController->getCache($cacheKey);
 
        if ($cacheRes) {
            return json_decode($cacheRes, true);
        } else {
            $res = (new DepService())->getDepListNoPage($args,[],['catid','catname']);
 
            if ($res) {
                $GeneralController->saveCache($cacheKey, json_encode($res));
                return $res;
            }
 
            return false;
        }
    }
 
 
    /**
     * 获取医生疾病标签
     * @param $doctor_id
     * @param int $is_check 是否包含医生未审核标签,0:不包含,1:包含;默认:1;
     * @param int $limit
     * @param int $strlen 字符长度
     * @return array|mixed
     */
    protected static function getDocDiseaseTag($doctor_id, $is_check = 1, $limit = 10, $strlen=0)
    {
        $params = [
            'doctor_id' => $doctor_id,
            'is_check' => $is_check,
            'limit' => $limit,
        ];
 
        $res = IllService::getDocDiseaseTag($params);
 
        if ($res['rows']) {
            $data = array_column($res['rows'], 'ill_name', 'ill_id');
            $data = array_slice($data, 0, $limit);
 
            if($strlen>0){
                $data = explode('|',mb_substr(implode('|',$data), 0, $strlen+count($data)-1, 'utf-8'));
                $data = array_slice($data, 0, count($data)-1);
            }
            return $data;
        }
        return [];
    }
 
    /**
     * 获取医生擅长
     * @param $doctorId
     * @return array
     */
    protected static function getDocExpert($doctorId)
    {
        $res = (new DoctorService())->doctorDetail($doctorId);
 
        if ($res) {
            return $res['expert'];
        }
 
        return [];
    }
 
    /**
     * 医生职称
     * @return array|mixed
     */
    protected static function getDoctorZc()
    {
        $GeneralController = new GeneralController();
        $GeneralController->shutDownCache = 0; //禁用手动关闭缓存
 
        $cacheKey = 'doctorZc_' . md5('zc');
        $cacheRes = $GeneralController->getCache($cacheKey);
        if ($cacheRes) {
            return json_decode($cacheRes, true);
        } else {
            //医生职称
            $DoctorService = new DoctorService();
            $res = $DoctorService->findDocZcList();
            if ($res) {
                $zc = array_column($res, 'zc_name', 'zc_id');//职称名称列表
                $GeneralController->saveCache($cacheKey, json_encode($zc));
 
                return $zc;
            }
            return [];
        }
    }
 
    /**
     * 根据条件查询医生职称
     * @return array|mixed
     */
    protected static function getChildDoctorZc($parentId=30)
    {
        $GeneralController = new GeneralController();
        $GeneralController->shutDownCache = 0; //禁用手动关闭缓存
 
        $cacheKey = 'childDoctorZc_' . md5('zc');
        $cacheRes = $GeneralController->getCache($cacheKey);
 
        if ($cacheRes) {
            return json_decode($cacheRes, true);
        } else {
            //医生职称
            $res = DoctorService::getDocZcList($parentId);
 
            if ($res) {
                $zc = array_slice(array_column($res, 'zc_name', 'zc_id'), 0, 4, true);//职称名称列表
 
                $GeneralController->saveCache($cacheKey, json_encode($zc));
 
                return $zc;
            }
            return [];
        }
    }
 
    /**
     * ajax统一返回json数据格式
     * @param $data
     * @param int $status
     * @param string $msg
     */
    public function ajaxReturn($data, $status = 0, $msg = '')
    {
        $res = [
            'status' => $status,
            'msg' => $msg,
            'data' => $data,
        ];
        exit(json_encode($res));
    }
 
    /**
     * 根据分值计算星级
     *
     * @access private
     * @param  int      $score  分值
     * @return float    星级数量
     */
    private function star($score) {
        $stars = 0; //星星颗数
        if(empty($score)) {
            return $stars;
        }
 
        $score = floatval($score);
        foreach ($this->starInterval as $key => $value) {
 
            list($start, $end) = $value;
 
            if($start < $score && $score <= $end){
                $stars = $key;
            }elseif($score > 10){
                $stars = 5;
            }
        }
 
        return $stars;
    }
 
}
#5Joy\Ill\Controllers\ConsultController->initialize()
#6Phalcon\Dispatcher->dispatch()
#7Phalcon\Mvc\Application->handle()
<?php
namespace Joy;
 
use Phalcon\Logger, Phalcon\Logger\Formatter\Line as LineFormatter, Phalcon\Exception as Exception, Phalcon\Logger\Multiple as MultipleStream;
use Phalcon\Net\Http;
use Phalcon\Security\Encrypter;
 
/**
 *
 * @author dancebear
 *
 * @property \Phalcon\Cache\BackendInterface $cache
 * @property \Phalcon\Security $security
 *
 */
class Application extends \Phalcon\Mvc\Application
{
 
    /**
     *
     * @var string
     */
    protected $_basePath;
 
    /**
     *
     * @var string
     */
    protected $_runtimePath;
 
    /**
     * 日志组件
     *
     * @var \Phalcon\Logger\AdapterInterface
     */
    protected $_logger;
 
    /**
     * 应用程序的命名空间
     *
     * @var string
     */
    public $defaultNamespace;
 
    /**
     * 配置文件目录
     *
     * @var string
     */
    protected $_configPath;
 
    /**
     *
     * @var string 终端用户所使用的字符集,推荐使用
     *      [IETF language tags](http://en.wikipedia.org/wiki/IETF_language_tag),例如:`en`代表英语。
     *      `en-US`代表英语(美国).
     * @see sourceLanguage
     */
    public $language = 'zh-CN';
 
    /**
     *
     * @var string 应用程序中所使用的语言
     *      这主要指的是信息和视图文件所使用的语言。
     * @see language
     */
    public $sourceLanguage = 'en-US';
 
    /**
     *
     * @param \Phalcon\DiInterface $di
     */
    public function __construct($di = null)
    {
        parent::setDI(\Joy::$di);
        \Joy::$app = $this;
    }
 
    /**
     * (non-PHPdoc)
     *
     * @see \Phalcon\DI\Injectable::__get()
     */
    public function __get($property)
    {
        if (method_exists($this, 'get' . $property))
            return $this->{'get' . ucfirst($property)}();
        if ($this->_dependencyInjector->has($property)) {
            return $this->_dependencyInjector->getShared($property);
        }
    }
 
    /**
     * 加载通过Composer安装的库
     */
    protected function loadComposerLib()
    {
        /**
         * load composer lib
         */
        if (file_exists($this->_basePath . '/../vendor/autoload.php'))
            require ($this->_basePath . '/../vendor/autoload.php');
    }
 
    /**
     * 加载配置文件
     *
     * @param string|\Phalcon\Config|array $file
     *            配置文件路径,此文件必须返回一个配置信息数组
     * @return \Joy\Application
     */
    public function configure($file)
    {
        if (! is_string($file)) {
            $configData = $file;
            $this->_configPath = null;
        } else {
            if (! file_exists($file)) {
                throw new Exception('The configuration file unfound:'.$file);
            }
            /**
             * Read the configuration
             */
            $configData = include ($file);
            $this->_configPath = basename($file);
        }
        $config = new \Phalcon\Config($configData);
        \Joy::$config = $config;
        $this->defaultNamespace = $config->defaultNamespace;
        $this->setBasePath($config->basePath);
        $this->setRuntimePath($config->runtimePath);
        return $this;
    }
 
    /**
     * 设置应用程序根目录
     *
     * @param string $path
     */
    public function setBasePath($path)
    {
        $this->_basePath = $path;
    }
 
    /**
     * 返回应用程序根目录
     *
     * @return string
     */
    public function getBasePath()
    {
        return $this->_basePath;
    }
 
    /**
     * 获取应用程序的模块目录
     *
     * @return string 应用程序模块目录。默认为{@link basePath}的子目录`Modules`。
     */
    public function getModulePath()
    {
        if ($this->_modulePath !== null)
            return $this->_modulePath;
        else
            return $this->_modulePath = $this->getBasePath() . DIRECTORY_SEPARATOR . 'Modules';
    }
 
    /**
     * 设置应用程序的模块目录
     *
     * @param string $value
     *            应用程序的模块目录
     * @throws Exception 无效的模块目录
     */
    public function setModulePath($value)
    {
        if (($this->_modulePath = realpath($value)) === false || ! is_dir($this->_modulePath))
            throw new Exception(\Joy::t('Joy', 'The module path "{path}" is not a valid directory.', array(
                '{path}' => $value
            )));
    }
 
    /**
     * 设置运行时应用程序目录
     *
     * @param string $path
     */
    public function setRuntimePath($path)
    {
        $this->_runtimePath = $path;
    }
 
    /**
     * 取得运行时文件目录
     *
     * @return string
     */
    public function getRuntimePath()
    {
        return $this->_runtimePath;
    }
 
    /**
     * 设置应用程序日志组件;日志组件允许同时使用多种日志输出方式
     *
     * @link http://docs.phalconphp.com/en/latest/reference/logging.html#adapters
     * @see \Phalcon\Logger\Multiple
     * @see \Phalcon\Logger\Adapter\File
     *
     * @throws Exception
     */
    protected function setLogger()
    {
        \Joy::$di->set('logger', function ()
        {
            $logger = new MultipleStream();
            // get environment variables
            $hostName = getenv('host');
            if ($hostName === false) {
                $logger->log('environment variables "host" for logger is not exists', Logger::ERROR);
                // throw new Exception('environment variables "host" for logger is not exists');
                $hostName = 'localhost';
            }
            foreach (\Joy::$config->components->logger as $adapter => $loggerConfig) {
                $adapter = '\Phalcon\Logger\Adapter\\' . $adapter;
                $_config = isset($loggerConfig[1]) ? $loggerConfig[1] : null;
                $_logger = new $adapter($loggerConfig[0], $_config);
                $logger->push($_logger);
            }
            $formatter = new LineFormatter($hostName . '-%date% - %message%');
            $logger->setFormatter($formatter);
            return $logger;
        });
    }
 
    /**
     * 设置应用程序的控制器模块信息
     * 系统会依据配置文件中的modules区块来启用相应的模块。
     * 以下是一个相应配置的实例:
     * ```
     * return [
     * 'components' => [
     * ],
     * 'modules' => [
     * 'User'
     * ]
     * ]
     * ```
     * 上述例子启用了一个名为User的模块,相应的程序目录为:
     * ``app/Modules/User``
     * 在此目录下包含相应的``Controllers`` ``Models`` ``Views``目录。
     * User目录的下还可以通过一个名为``Module.php``的文件来继承``Joy\Web\Module``类来实现模块的一些自定义设置。
     */
    protected function setModules()
    {
        $namespaces = [];
        foreach ((array) \Joy::$config->modules as $module) {
            $moduleClassFile = $this->getModulePath() . DIRECTORY_SEPARATOR . $module . '/Module.php';
            $moduleClass = $this->defaultNamespace . '\\' . $module . '\Module';
            if (! file_exists($moduleClassFile)) {
                $moduleClassFile = JOY_PATH . '/Web/Module.php';
                $moduleClass = 'Joy\Web\Module';
            }
            $modules[$module] = array(
                'className' => $moduleClass,
                'path' => realpath($moduleClassFile),
                'moduleName' => $module
            );
            $namespaces[$this->defaultNamespace . '\\' . $module] = $this->getModulePath() . DIRECTORY_SEPARATOR . $module;
        }
        $namespaces[$this->defaultNamespace . '\\Controllers'] = $this->getBasePath() . '/Controllers';
        $namespaces[$this->defaultNamespace . '\\Models'] = $this->getBasePath() . '/Models';
        \Joy::$di->get('loader')->registerNamespaces($namespaces, true);
    }
 
    /**
     * 设置系统的事件管理器
     * 这里将实例化一个``\Phalcon\Events\Manager``类,并将它注册微系统的默认事件管理器。
     */
    protected function setEvents()
    {
        $this->setEventsManager(new \Phalcon\Events\Manager());
    }
 
    /**
     * 设置找不到页面的事件
     */
    protected function setNotFound()
    {
        $self = &$this;
        \Joy::$di->set('dispatcher', function () use($self) {
            $eventsManager = new \Phalcon\Events\Manager();
            // Attach a listener
            $eventsManager->attach("dispatch:beforeException", function ($event, $dispatcher, $exception) use($self) {
 
                // Handle 404 exceptions
                if ($exception instanceof \Phalcon\Mvc\Dispatcher\Exception) {
                    $self->sendErrorPage();
                }
                // Alternative way, controller or action doesn't exist
                if ($event->getType() == 'beforeException') {
                    switch ($exception->getCode()) {
                        case \Phalcon\Dispatcher::EXCEPTION_HANDLER_NOT_FOUND:
                        case \Phalcon\Dispatcher::EXCEPTION_ACTION_NOT_FOUND:
                        $self->sendErrorPage();
                    }
                }
            });
            $dispatcher = new \Phalcon\Mvc\Dispatcher();
            // Bind the EventsManager to the dispatcher
            $dispatcher->setEventsManager($eventsManager);
            return $dispatcher;
        }, true);
    }
 
    /**
     * 输出错误信息或错误页面
     */
    private function sendErrorPage()
    {
        $config = \Joy::$config;
        $config = $config->toArray();
        http_response_code(404);
        if ($config['render'] == 'json') {
            $this->response->setJsonContent([
                'status' => 404,
                'message' => 'page not found'
            ])->send();
        } else {
            $errorPage = JOY_PATH . '/Web/error/404.php';
            if (isset($config['error']['404'])) {
                $custom = ROOT_PATH . $config['error']['404'];
                if (file_exists($custom))
                    $errorPage = $custom;
            }
            include_once $errorPage;
        }
        exit();
    }
    /**
     * 初始化系统的视图组件,支持直接使用PHP模板和volt模板引擎
     *
     * @return \Phalcon\Mvc\View
     */
    protected function setView()
    {
        /**
         * Setting up the view component
         */
        \Joy::$di->set('view', function ()
        {
            $view = new \Phalcon\Mvc\View();
            $volt = new \Phalcon\Mvc\View\Engine\Volt($view, \Joy::$di);
            $php = new \Phalcon\Mvc\View\Engine\Php($view, \Joy::$di);
            $config = \Joy::$config->application->views;
            $volt->setOptions([
                "compiledPath" => function ($templatePath) use($config)
                {
                    $templatePath = str_replace(DIRECTORY_SEPARATOR, $config->compiledSeparator, str_replace(realpath(\Joy::$config->basePath), '', realpath($templatePath)));
                    return $config->compiledPath . '/' . $templatePath . $config->compiledExtension;
                },
 
                // 'compiledExtension' => $config->compiledExtension,
                // 'compiledSeparator' => $config->compiledSeparator,
                'compileAlways' => JOY_DEBUG && $config->compileAlways
            ]);
 
            $view->setViewsDir($config->dir);
            $view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_LAYOUT);
 
            $view->registerEngines([
                ".volt" => $volt,
                '.php' => $php
            ]);
 
            if (JOY_DEBUG) {
                $em = $this->getEventsManager();
                $em->attach("view", function ($event, $view)
                {
                    if ($event->getType() == 'beforeRender') {
                        if (! $view->renderStart)
                            $view->renderStart = microtime(true);
                    }
                    if ($event->getType() == 'afterRender') {
                        $output = $view->getContent();
                        $timestamp = microtime(true);
                        $viewTime = round($timestamp - $view->renderStart, 3);
                        $totleTime = round($timestamp - JOY_BEGIN_TIME, 3);
                        if (\Joy::$di->has('profiler')) {
                            /**
                             *
                             * @var \Phalcon\Db\Profiler $profiler
                             */
                            $dbProfiler = \Joy::$di->get('profiler');
                            $querys = 'Total ' . $dbProfiler->getNumberTotalStatements() . ' query';
                            $costs = 'Cost ' . round($dbProfiler->getTotalElapsedSeconds(), 3) . 's';
                        } else {
                            $querys = '';
                            $costs = '';
                        }
                        $output = strtr($output, [
                            '<!-- {total} -->' => 'Page:' . $totleTime . 's',
                            '<!-- {view} -->' => 'View:' . $viewTime . 's',
                            '<!-- {querys} -->' => $querys,
                            '<!-- {costs} -->' => $costs
                        ]);
                        $view->setContent($output);
                        // $di->get('logger')->log('渲染客户端js、css结束'.json_encode($view));
                        return $view;
                    }
                    if ($event->getType() == 'notFoundView') {
                        throw new Exception('View not found - "' . $view->getActiveRenderPath() . '"');
                    }
                });
                $view->setEventsManager($em);
            }
 
            return $view;
        });
    }
 
    /**
     * 设置数据库事件探查器
     *
     * @return \Phalcon\Db\Profiler
     */
    protected function setProfile()
    {
        \Joy::$di->set('profiler', function ()
        {
            return new \Phalcon\Db\Profiler();
        }, true);
    }
 
    /**
     * 根据配置文件信息添加mongo数据库实例
     */
    protected function setMongo()
    {
        if (\Joy::$config->components->offsetExists('mongo')) {
            $config = \Joy::$config->components->mongo->toArray();
        } else {
            $config = [];
        }
        if (count($config) > 0) {
            \Joy::$di->set(
                'mongo',
                function () use ($config) {
                    $collection = $config['username'] . ':' . $config['password'] . '@' . $config['host'];
                    $options = [
                        'connectTimeoutMS' => 1000
                    ];
                    if (strpos($config['host'], ",") > 0) { //集群情况,需增加参数
                        $options['replicaSet'] = 'rep';
                        $options['readPreference'] = 'nearest';
                    }
                    //$mongo = new \Phalcon\Db\Adapter\Mongo\Client("mongodb://".$collection,$options);
                    $mongo = new \Phalcon\Db\Adapter\Mongo\Client("mongodb://" . $collection . ($config['dbname'] ? '/' . $config['dbname'] : ''), $options);
                    return $mongo->selectDB($config['dbname']);
                },
                true
            );
        }
    }
 
    /**
     * 根据配置文件信息添加数据库实例
     */
    protected function setDatabase()
    {
        $config = \Joy::$config->components->database;
        if ($config->count() > 0) {
            foreach ($config as $name => $database) {
                $this->addDatabase($name, $database);
            }
        }
    }
 
    /**
     * 设置数据库连接
     * 请在配置文件的components的database小节下添加
     * ```
     * 'db' => [
     * 'adapter' => 'Mysql',
     * 'host' => 'localhost',
     * 'username' => 'root',
     * 'password' => 'root',
     * 'dbname' => 'tool',
     * 'options' => [
     * PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
     * ],
     * ]
     * ```
     * 其内容依据使用的数据库类型不同而有所区别,具体请参考(@link http://docs.phalconphp.com/en/latest/reference/db.html)
     * 他会自动添加一个名为db的数据库实例;使用方法示例:
     * ```
     * $db=\Joy::$di->get('db');
     * ```
     *
     * @param string $name
     * @param \Phalcon\Config $config
     * @return \Phalcon\Db\AdapterInterface
     */
    public function addDatabase($name, \Phalcon\Config $config)
    {
        /**
         * Database connection is created based in the parameters defined in the configuration file
         */
        \Joy::$di->set($name, function () use($config,$name)
        {
 
            $eventsManager = $this->getEventsManager();
            $adapter = '\Phalcon\Db\Adapter\Pdo\\' . $config->adapter;
            /**
             * @var $connection \Phalcon\Db\Adapter
             */
            try{
                $connection = new $adapter($config->toArray());
            }catch (\Exception $exception){
                $this->addMonitor($exception, $config->adapter, $config->host, $config->dbname);
                throw new Exception('数据库连接失败');
                $connection = null;
            }
 
            // 设置SQL优化日志
            if (JOY_DEBUG || (defined('JOY_DB_DEBUG') && JOY_DB_DEBUG)) {
                $logFile = $this->getRuntimePath() . '/logs/';
                if(!is_dir($logFile)){
                    mkdir($logFile, 0777, true);
                }
                // Attach logger & profiler
                $logger = new \Phalcon\Logger\Adapter\File($logFile.$name.'.log');
                /**
                 * @var $profiler \Phalcon\Db\Profiler
                 */
                $profiler = \Joy::$di->getProfiler();
 
                $eventsManager->attach($name, function ($event, $connection) use($logger, $profiler)
                {
                    if ($event->getType() == 'beforeQuery') {
                        $statement = $connection->getSQLStatement();
                        $profiler->startProfile($statement);
                    }
                    if ($event->getType() == 'afterQuery') {
                        // Stop the active profile
                        $profiler->stopProfile();
                        $last = $profiler->getLastProfile();
                        $logger->log($last->getSQLStatement()."\t\t" .json_encode($last->getSQLVariables())."\t\t" .$last->getTotalElapsedSeconds(), \Phalcon\Logger::DEBUG);
                    }
                });
                $connection->setEventsManager($eventsManager);
            }
            return $connection;
        });
    }
 
    /**
     * 设置数据库元数据的缓存
     * 支持以下的元数据存储方式:
     * Memory、Memcache、Redis
     *
     * @return \Phalcon\Mvc\Model\MetaData\Memory
     */
    protected function setMetaData()
    {
        \Joy::$di['modelsMetadata'] = function ()
        {
            /* @var $config \Phalcon\Config  */
            $config = \Joy::$config->components->metadata;
            $adapter = '\Phalcon\Mvc\Model\MetaData\\' . $config->get('adapter', 'Memory');
            $configDefault = new \Phalcon\Config([
                "lifetime" => 86400,
                "prefix" => "my-prefix"
            ]);
            // Instantiate a meta-data adapter
            $metaData = new $adapter($configDefault->merge($config));
 
            // Set a custom meta-data database introspection
            // 此处是设置支持字段别名
            if(\Phalcon\Version::get()>'2.0'){
              $Annotations = '\Phalcon\Mvc\Model\MetaData\Strategy\Annotations';
            }else{
              $Annotations = '\Phalcon\Mvc\Model\MetaData\Strategy\AnnotationsMetaData';
            }
 
            $metaData->setStrategy(new $Annotations());
 
            return $metaData;
        };
    }
 
    /**
     * 设置全局的模型管理器
     *
     * @return \Phalcon\Mvc\Model\Manager
     */
    protected function setModelsManager()
    {
        \Joy::$di->setShared('modelsManager', function ()
        {
            $eventsManager = new \Phalcon\Events\Manager();
            $modelsManager = new \Phalcon\Mvc\Model\Manager();
            $modelsManager->setEventsManager($eventsManager);
            return $modelsManager;
        });
    }
 
    /**
     * 设置缓存组件
     * 缓存的配置信息如下:
     * ```
     * 'cache' =>[
     * 'adapter' => 'Memcache',
     * 'host' => '127.0.0.1',
     * 'port' => 11211,
     * 'persistent' => 1
     * ]
     * ```
     * 如果您需要使用多台memcache服务器,请使用``Libmemcached``组件
     * 我们的系统支持下列组件:
     * ``File``、``Memcached``、``APC``、``Mongo``、``XCache``、``Redis``
     * 同时,我们还可以很方便的扩展更多的组件。关于各组件的配置方式请参考:
     * [@link http://docs.phalconphp.com/en/latest/reference/cache.html#backend-adapters cache]
     * 其中libMemcached与memcache的配置有所区别,请务必注意。
     * 如果需要配置多个缓存组件,请使用如下格式的配置文件:
     * ```
     * 'cache'=>[
     * [
     * [
     * ],
     * 'redis'=>[
     * ],
     * 'Mongo' => [
     * ]
     * ]
     * ]
     * ```
     * 数组的键将会被作为缓存的组件名的一部分,其中这个数组的KEY为0的初始化后的组件将被
     * 作为默认的缓存使用。缓存组件名的格式为:
     * ``cache_[[key]]``。
     */
    protected function setCache()
    {
        if (\Joy::$config->components->offsetExists('cache')) {
            $config = \Joy::$config->components->cache->toArray();
        } else {
            $config = [];
        }
        if (count($config['backend']) > 0) {
            $adapter = '\Phalcon\Cache\Frontend\\' . $config['frontend'];
            $frontCache = new $adapter(array(
                "lifetime" => 172800
            ));
            foreach ($config['backend'] as $key => $_config) {
                $adapter = '\Phalcon\Cache\Backend\\' . $_config['adapter'];
                unset($_config['adapter']);
                $cache = new $adapter($frontCache, $_config);
                $cacheKey = 'cache';
                if ($key !== 0) {
                    $cacheKey = 'cache_' . $key;
                }
                \Joy::$di->set($cacheKey, $cache);
            }
        }
    }
 
    /**
     * 设置密码安全及CSRF组件
     *
     * @return \Phalcon\Security
     */
    public function setSecurity()
    {
        \Joy::$di->set('security', function ()
        {
 
            $security = new \Phalcon\Security();
            $workFactor = 8;
            $config = \Joy::$config->components->toArray();
            if (isset($config['security']) && isset($config['security']['workFactor']))
                $workFactor = $config['security']['workFactor'];
                // Set the password hashing factor to 12 rounds
            $security->setWorkFactor($workFactor);
 
            return $security;
        }, true);
    }
 
    /**
     * 注册数据加密/解密服务
     */
    public function setEncrypter()
    {
        \Joy::$di->set('encrypter', function() {
            return new Encrypter();
        }, true);
    }
 
    /**
     * 注册数据加密/解密服务
     */
    public function setPhpcat()
    {
        if (\Joy::$config->components->offsetExists('phpcat')) {
            \Joy::$di->set('phpcat', function() {
                $config = \Joy::$config->components->phpcat->toArray();
                return new \PhpCat\PhpCat($config['domain'],$config['servers']);
            }, true);
        }
    }
 
 
    /**
     * 初始化系统组件
     * debug模式时会使用Phalcon\Debug进行调试
     * 否则会输出错误页面
     *
     * @throws \Phalcon\Exception
     * @return \Joy\Application
     */
    public function init()
    {
        if (JOY_DEBUG) {
            $debug = new \Phalcon\Debug();
        } else {
            $debug = new Debug();
            $debug->setView(\Joy::$config->errorPage);
        }
        $debug->setUri(JOY_DEBUG_URI);
        $debug->listen();
        $this->setPhpcat(); //设置PHP的cat监控
        $this->setEvents();
        $this->setLogger();
        $this->loadCustomNamespaces();
        $this->setModules();
        $this->setView();
        $this->setMongo();
        $this->setProfile();
        $this->setNotFound();
        $this->setDatabase();
        $this->setCache();
        $this->setModelsManager();
        $this->setMetaData();
        $this->setSecurity();
        $this->setEncrypter();  //设置数据的加密和解密方法
        return $this;
    }
 
    /**
     * 执行应用程序并处理异常
     */
    public function run()
    {
      $stage = getenv('APPLICATION_STAGE') ? getenv('APPLICATION_STAGE') : '';
      if(is_file(ROOT_PATH . "/config/web.{$stage}.php")){
        $stage_config = ROOT_PATH . "/config/web.{$stage}.php";
      }else{
        $stage_config = ROOT_PATH . "/config/web.php";
      }
        echo $this->configure($stage_config)
            ->init()
            ->handle()
            ->getContent();
    }
 
    /**
     * 输出debug信息
     *
     * @param string $message
     * @param string $context
     */
    public function debug($message, $context = null)
    {
        if ($this->_logger == null) {
            $this->_logger = \Joy::$di->get('logger');
        }
        $this->_logger->debug($message, $context);
    }
 
    /**
     * 加载自定义命名空间
     */
    protected function loadCustomNamespaces()
    {
        $custom_namespaces = \Joy::$config->offsetExists('customNamespaces') ? \Joy::$config->customNamespaces->toArray() : '';
        if($custom_namespaces){
            \Joy::$di->get('loader')->registerNamespaces($custom_namespaces, true);
        }
    }
 
    /**
     * 添加日志
     * @param $resourceType 资源类型: 数据库,Memcache, Redis , 文件 ,日志服务 其它
     * @param $host  主机IP
     * @param $dbName  哪个数据库
     */
    protected function addMonitor($exception, $resourceType, $host, $dbName){
        if (\Joy::$config->components->offsetExists('phpcat')) {
            \Joy::$di->get("phpcat")->logException("Error", "database.".$resourceType.".connect.error", $exception);
        }
        $components = \Joy::$config->components->toArray();
        if(empty($components['monitor'])){
            return true;
        }
        $http = new  Http();
        $http->timeOut = 1;
        $data = [
            'channel_id'=>$components['monitor']['channelId'],
            'business_type'=>$components['monitor']['businessType'],
            'log_level' => 'ERROR',
            'position' => $this->router->getControllerName().'_'.$this->router->getActionName(),
            'msg' => $resourceType.'-'.$dbName.'连接服务器'. $host.'失败'
        ];
        $result = $http->post($components['monitor']['apiUrl'], $data);
        if($result['status']==2){
            return false;
        }
        return true;
    }
}
#8Joy\Application->run()
<?php
/*
 * @Descripttion: 
 * @version: v2
 * @Author: michael_sail
 * @Date: 2021-01-13 15:08:38
 * @LastEditors: michael_sail
 * @LastEditTime: 2021-07-07 18:38:00
 */
/**
 * @desc phalcon框架入口
*/
header("Content-type: text/html; charset=utf-8");
/**
 * 网页入口文件
*/
$stage = getenv('APPLICATION_STAGE') ? getenv('APPLICATION_STAGE') : 'development';
if ($stage == 'production') {
    defined('JOY_DEBUG') or define('JOY_DEBUG', false);
} else {
    defined('JOY_DEBUG') or define('JOY_DEBUG', true);
}
defined('JOY_DB_DEBUG') or define('JOY_DB_DEBUG', false);
 
defined('JIUYI_ROOT_PATH') or define('JIUYI_ROOT_PATH', dirname(__FILE__));//91160网站根目录
defined('VENDOR_PATH') OR define('VENDOR_PATH', JIUYI_ROOT_PATH . '/../../api/framework');//第三方库目录
defined('ROOT_PATH') or define('ROOT_PATH', JIUYI_ROOT_PATH . '/../../api/rrjk160-disease');//网站根目录
defined('APP_PATH') or define('APP_PATH', ROOT_PATH . '/app');
 
define('STATIC_VERSION', '202107071837');
//定义PHP执行方式
define('IS_CLI',PHP_SAPI=='cli'? true : false);
// if (!IS_CLI && isset($_GET['ssskid'])) {
//     setcookie('FISKCDDCC', $_GET['ssskid'], 0, '/', '.rrjk160.com');
// }
define('BASE_DOMAIN', '.rrjk160.com');
if(IS_CLI){
    //为命令行调试模式,设置默认城市
    define('DOMAIN_HOST', 'www.rrjk160.com');
    define('WEBAPI_FROM', 'www');
    $args = $argv;
    array_shift($args);
    $_SERVER['REQUEST_URI'] = '/'.implode('/', $args).'.html';
}else{
    define('DOMAIN_HOST', strtolower($_SERVER['HTTP_HOST']));
    define('WEBAPI_FROM', substr(DOMAIN_HOST, 0, -(strlen(BASE_DOMAIN))));
}
 
include VENDOR_PATH . '/Joy.php';
Joy::$di->get('loader')->registerNamespaces([
    'Joy\Api'=>APP_PATH.'/Api',
    'Joy\Library'=>APP_PATH.'/Library/'
], true);
(new \Joy\Web\Application())->run();
KeyValue
_url/consult/index.html
KeyValue
NLS_LANGAMERICAN_AMERICA.AL32UTF8
ORACLE_HOME/usr/lib/oracle/11.2/client64/lib
USERnobody
HOME/
FCGI_ROLERESPONDER
SCRIPT_FILENAME/app/wwwroot/rrjk160-com/91web/consult_index.php
QUERY_STRING_url=/consult/index.html
REQUEST_METHODGET
CONTENT_TYPE
CONTENT_LENGTH
SCRIPT_NAME/consult_index.php
REQUEST_URI/consult/index.html
DOCUMENT_URI/consult_index.php
DOCUMENT_ROOT/app/wwwroot/rrjk160-com/91web
SERVER_PROTOCOLHTTP/1.1
GATEWAY_INTERFACECGI/1.1
SERVER_SOFTWAREnginx/1.16.0
REMOTE_ADDR192.168.1.105
REMOTE_PORT30640
SERVER_ADDR10.8.34.33
SERVER_PORT80
SERVER_NAMEwww.rrjk160.com
REDIRECT_STATUS200
PHALCON_ENVproduction
HTTP_HOSTwww.rrjk160.com
HTTP_X_REAL_IP47.108.137.19
HTTP_X_FORWARDED_FOR216.73.217.174, 47.108.137.19
HTTP_X_FORWARDED_PROTOhttps
HTTP_X_FORWARDED_PORT443
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
HTTP_ACCEPT_ENCODINGgzip, br, zstd, deflate
HTTP_REFERERhttp://www.rrjk160.com/consult/index.html
HTTP_COOKIEFISKCDDCC=2d34951a382dc335ec7cb4ffed8e5442; land_referrer=https%3A%2F%2Frrjk160.com%2F; land_url=https%3A%2F%2Fwww.rrjk160.com%2F; ip_city=sz; __guid=VFBAME6acab8fb768de1.69517122
PHP_SELF/consult_index.php
REQUEST_TIME_FLOAT1791670524.3829
REQUEST_TIME1791670524
#Path
0/app/wwwroot/rrjk160-com/91web/consult_index.php
1/app/wwwroot/api/framework/Joy.php
2/app/wwwroot/api/framework/vendor/autoload.php
3/app/wwwroot/api/framework/vendor/composer/autoload_real.php
4/app/wwwroot/api/framework/vendor/composer/ClassLoader.php
5/app/wwwroot/api/framework/vendor/composer/autoload_namespaces.php
6/app/wwwroot/api/framework/vendor/composer/autoload_psr4.php
7/app/wwwroot/api/framework/vendor/composer/autoload_classmap.php
8/app/wwwroot/api/framework/Web/Application.php
9/app/wwwroot/api/framework/Application.php
10/app/wwwroot/api/rrjk160-disease/config/web.php
11/app/wwwroot/api/rrjk160-disease/app/Controllers/Routes.php
12/app/wwwroot/api/rrjk160-disease/app/Controllers/ConsultController.php
13/app/wwwroot/api/rrjk160-disease/app/Controllers/GeneralController.php
14/app/wwwroot/api/rrjk160-disease/app/Controllers/Controller.php
15/app/wwwroot/api/framework/Web/Controller.php
16/app/wwwroot/api/rrjk160-disease/app/Api/BaseService.php
17/app/wwwroot/api/rrjk160-disease/app/Library/Tools.php
18/app/wwwroot/api/rrjk160-disease/app/Library/City.php
19/app/wwwroot/api/rrjk160-disease/app/Api/AreaService.php
20/app/wwwroot/api/rrjk160-disease/app/Api/InformationService.php
Memory
Usage10747904