AbstractController.class.php 6.37 KB
<?php
/**
 * Created by PhpStorm.
 * User: zhoutao
 * Date: 2018/1/8
 * Time: 下午3:54
 */

namespace Apicp\Controller\LiveRoom;

use Com\Cookie;
use Com\Error;
use Common\Common\Cache;
use Common\Service\MainService;
use Common\Service\StudioService;
use Think\Cache\Driver\Redis;
use Think\Controller\RestController;
use Think\Exception;
use VcySDK\Service;

class AbstractController extends RestController
{
    /**
     * 管理员身份标识存活时长 (秒)
     */
    const ADMINER_ID_EXPIRE_TIME = 15;

    /**
     * 返回结果
     *
     * @var array
     */
    protected $_result = array();

    /**
     * 是否验证登陆
     * @var bool
     */
    protected $requireLogin = true;

    /**
     * cookie
     *
     * @type null|Cookie
     */
    protected $_cookie = null;

    /**
     * 直播活动详情
     * @var null
     */
    protected $liveMainDetail = null;

    /**
     * 直播室详情
     * @var null
     */
    protected $studioDetail = null;

    public function before_action()
    {
        // 获取直播活动详情
        $lmId = I('post.lm_id', 0, 'rintval');
        if (empty($lmId)) {
            E('_EMPTY_LIVE_ID');
        }
        $mainServ = new MainService();
        $this->liveMainDetail = $mainServ->get($lmId, true);
        if (empty($this->liveMainDetail)) {
            E('_ERR_LIVE_IS_NOT_EXIST');
        }
        // 获取直播室详情
        $studioServ = new StudioService();
        $this->studioDetail = $studioServ->get_by_conds(['lm_id' => $lmId], [], true);
        if (empty($this->studioDetail)) {
            E('_ERR_MISS_LIVE_STUDIO_DATA');
        }
        // 延续 Cookie
        $this->continueCookie($this->liveMainDetail['domain']);
        // 验证 token
        $this->validateLoginLiveRoom($this->studioDetail['stream_id']);

        // 初始化SDK
        $cache = &Cache::instance();
        $this->config = $cache->get('Common.EnterpriseConfig', '', ['prefix' => $this->liveMainDetail['domain'] . '_']);
        $config = array(
            'apiUrl' => cfg('UC_APIURL'),
            'enumber' => $this->liveMainDetail['domain'],
            'appid' => $this->config['wxqyCorpid'],
            'pluginIdentifier' => APP_IDENTIFIER,
            'thirdIdentifier' => cfg('SDK_THIRD_IDENTIFIER'),
            'logPath' => RUNTIME_PATH . '/Logs/VcySDK/',
            'apiSecret' => cfg('API_SECRET'),
            'apiSigExpire' => cfg('API_SIG_EXPIRE'),
            'fileConvertApiUrl' => cfg('FILE_CONVERT_API_URL')
        );
        $service = &Service::instance();
        $service->initSdk($config);

        return true;
    }

    /**
     * 延续 Cookie (不然用户还在后台的话 回去会丢失 Cookie)
     * @param $domain
     */
    public function continueCookie($domain)
    {
        // 初始化 Cookie
        $cookieDomain = cfg('COOKIE_DOMAIN');
        $expired = cfg('COOKIE_EXPIRE');
        $secret = md5(cfg('COOKIE_SECRET') . $domain);
        $this->_cookie = &Cookie::instance($cookieDomain, $expired, $secret);
        ob_start(array($this->_cookie, 'send'));
    }

    /**
     * 后置操作
     *
     * @param string $action 操作名称
     *
     * @return bool
     */
    public function after_action($action = '')
    {

        $this->_response();

        return true;
    }

    /**
     * 重写输出方法
     *
     * @param $data
     * @param $type
     * @param $code
     *
     * @return bool
     */
    public function response($data, $type = 'json', $code = 200)
    {

        $this->_response($data, $type, $code);

        return true;
    }

    /**
     * 验证token
     *
     * @param int $stream_id 直播推流ID
     *
     * @return bool
     */
    public function validateLoginLiveRoom($stream_id)
    {
        // 不需登陆
        if (!$this->requireLogin) {
            return true;
        }

        // 获取cookie中的token
        $cookie_token = $this->_cookie->getx($stream_id);
        // 获取redis中的token值
        $redisServ = new Redis();
        $redis_token = $redisServ->get($stream_id);

        if (!empty($cookie_token)) {
            // 判断token是否相等
            if ($cookie_token == $redis_token) {
                // 更新 redis 过期时间
                $redisServ->set($stream_id, $redis_token, self::ADMINER_ID_EXPIRE_TIME);
                // 更新 Cookie 过期时间
                $this->_cookie->setx($stream_id, $redis_token, self::ADMINER_ID_EXPIRE_TIME);
            } else {
                // 登陆超时重新登录 清理 Cookie
                $this->_cookie->remove($this->studioDetail['stream_id']);
                E('_ERR_LOGIN_TIME_OUT');
            }
        } else {
            if (!empty($redis_token)) {
                // 别的地方登陆了
                E('_ERR_OTHER_PLACES_LANDED');
            } else {
                // 请登录
                E('_ERR_PLEASE_LOGIN');
            }
        }

        return true;
    }

    /**
     * 重写输出方法
     *
     * @param mixed  $data 输出数据
     * @param string $type 输出类型
     * @param int    $code 返回状态
     *
     * @see \Think\Controller\RestController::_response()
     */
    protected function _response($data = null, $type = 'json', $code = 200)
    {

        // 如果需要返回的是异常
        if ($data instanceof Exception) {
            // 如果是显示给用户的错误
            if ($data->is_show()) {
                Error::instance()->set_error($data);
            } else {
                // 如果是系统错误, 则显示默认错误
                $this->_set_error('_ERR_DEFAULT');
            }

            $data = '';
        } elseif ($data instanceof \Exception) {
            $code = $data->getCode();
            $message = $data->getMessage();

            if (! empty($message)) {
                Error::instance()->set_error($data);
            } else {
                // 系统报错
                $data = '';
                $this->_set_error('_ERR_DEFAULT');
            }
        }

        // 输出结果
        parent::_response(generate_api_result(null == $data ? $this->_result : $data), $type, $code);
    }

    /**
     * 设置错误信息
     *
     * @param mixed $message 错误信息
     * @param int   $code    错误号
     *
     * @return bool
     */
    protected function _set_error($message, $code = 0)
    {

        Error::instance()->set_error($message, $code);

        return true;
    }
}