| #4 | Joy\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"></i>{$consult_doctors[$k]['short_dep_name']}</span>
<span title="{$consult_doctors[$k]['unit_name']}" class="unit_name">
<i class="iconfont typo-qgray mr10"></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;
}
} |
| #7 | Phalcon\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;
}
} |