Room.php 12.8 KB
<?php

namespace app\models;

use Yii;
use common\lib\QcloudApi\Client as QcloudApiClient;
use common\models\RoomNums;
use common\models\Share;
use common\config\Params;

/**
 * This is the model class for table "{{%room}}".
 *
 * @property string $id
 * @property string $room_id
 * @property string $title
 * @property string $master_id
 * @property string $pic
 * @property integer $starting_time
 * @property string $starting_pic
 * @property string $secret
 * @property string $best
 * @property string $vest
 * @property integer $status
 * @property integer $create_time
 * @property integer $update_time
 */
class Room extends \yii\db\ActiveRecord
{
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%room}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['room_id', 'master_id', 'starting_time', 'best', 'vest', 'is_addup', 'living', 'status', 'unstart_sort', 'living_sort', 'create_time', 'update_time'], 'integer'],
            [['title', 'watermark'], 'string', 'max' => 100],
            [['app', 'secret'], 'string', 'max' => 50],
            [['pic', 'background_pic'], 'string', 'max' => 255],
            [['room_id'], 'unique'],
            [['secret'], 'unique'],
            [['pic', 'background_pic'], 'required'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'room_id' => '房间ID',
            'title' => '直播标题',
            'watermark' => '水印文案',
            'master_id' => '主播ID',
            'app' => '业务线',
            'secret' => '房间密钥',
            'pic' => '头图',
            'background_pic' => '背景图',
            'starting_time' => '预告开始时间',
            'best' => '是否精选',
            'vest' => '马甲状态',
            'living' => '直播状态',
            'status' => '房间状态',
            'unstart_sort' => '未开始排序',
            'living_sort' => '直播中排序',
            'create_time' => '创建时间',
            'update_time' => '更新时间',
        ];
    }
    
    public function behaviors() {
        return [
            [
                'class' => \yii\behaviors\TimestampBehavior::className(),
                'createdAtAttribute' => 'create_time',
                'updatedAtAttribute' => 'update_time',
            ]
        ];
    }
    
    /**
     * 关联表-主播
     * @return type
     */
    public function getMaster()
    {
        return $this->hasOne(Master::className(), ['master_id'=>'master_id']);
    }
    
    /**
     * 关联表-腾讯云直播频道
     * @return type
     */
    public function getRoomQchannel()
    {
        return $this->hasOne(RoomQchannel::className(), ['room_id'=>'room_id']);
    }
    
    /**
     * 关联表-正在录制的视频
     * @return type
     */
    public function getVideoRecording()
    {
        return $this->hasOne(Video::className(), ['room_id'=>'room_id'])->where(['and',['>','live_start_time',0],['live_end_time'=>0]])->orderBy(['create_time'=>SORT_DESC]);
    }

    /**
     * 关联表-计数
     * @return type
     */
    public function getRoomNums()
    {
        return $this->hasOne(RoomNums::className(), ['room_id'=>'room_id']);
    }
    /**
     * 生成房间ID
     */
    public function bornRoomId()
    {
        $max_id = (int)$this->find()->max('room_id');
        return $max_id ? $max_id+1 : 1001;
    }
    
    /**
     * 注入查询条件
     * @param array $condition
     */
    public static function condition($condition){
        $model = parent::find();
        foreach ($condition as $field=>$value){
            if ($field == 'keyword'){
                if (!empty($value)){
                    $model->alias('r')->joinWith('master m')->andWhere(['or',['room_id'=>$value],['r.master_id'=>$value],['like','title',$value],['like','m.name',$value]]);
                }
            }else{
                $model->andWhere([$field=>$value]);
            }
        }
        return $model;
    }
    
    /**
     * 创建直播间
     * @param array $data 直播间信息
     */
    public function create(array $data)
    {
        $transaction = $this->getDb()->beginTransaction();
        try{
            if (empty($data['app'])){
                throw new \Exception('未选择业务线');
            }
            if (!empty($data['starting_time'])){
                $data['starting_time'] = (int)strtotime($data['starting_time']);
                if ($data['starting_time'] <= time()){
                    throw new \Exception('预告开始时间不能早于当前时间');
                }
            } 
            
            $data['room_id'] = $this->bornRoomId();
            sort($data['app']);
            $data['app'] = implode(',', $data['app']);
            
            if ($data['best'] > 0){
                $count = $this->find()->where(['!=','best','0'])->count();
                if ($count >= 2){
                    throw new \Exception('精选房间上限是2个');
                }
            }
            
            $this->setAttributes($data);
            if (!$this->save()){
                throw new \Exception(current($this->getFirstErrors()));
            }

            $title = $this->title;
            $ret = QcloudApiClient::self()->CreateLVBChannel($title);
            if (!$ret){
                throw new \Exception(QcloudApiClient::self()->error());
            }

            $RoomQchannel = new RoomQchannel;
            $RoomQchannel->setAttributes([
                'room_id'=>$this->room_id,
                'channel_id'=>$ret['channel_id'],
                'upstream_address'=>$ret['channelInfo']['upstream_address'],
                'downstream_address'=>json_encode($ret['channelInfo']['downstream_address'],JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
            ]);
            if (!$RoomQchannel->save()){
                throw new \Exception(current($RoomQchannel->getFirstErrors()));
            }

            //插入分享内容
            $RoomShare = new Share;
            $RoomShare->setAttributes([
                'obj_id'=>$this->room_id,
                'type'=>Params::LIVE_SHARE_TYPE,
                'pic'=>$data['share_pic'],
                'title'=>$data['share_title'],
                'content'=>$data['share_content'],
            ]);
            if (!$RoomShare->save()){
                throw new \Exception(current($RoomShare->getFirstErrors()));
            }

            $transaction->commit();
            return $this->room_id;
        }catch (\Exception $e) {
            $transaction->rollBack();
            Yii::$app->session->setFlash('warning', $e->getMessage());
            return false;
        }
        
    }
    
    /**
     * 编辑直播间
     * @param array $data 直播间信息
     */
    public function edit(array $data)
    {
        $transaction = $this->getDb()->beginTransaction();
        try{
            if (empty($data['app'])){
                throw new \Exception('未选择业务线');
            }
            if (!empty($data['starting_time'])){
                $data['starting_time'] = (int)strtotime($data['starting_time']);
                if ($data['starting_time'] <= time()){
                    throw new \Exception('预告开始时间不能早于当前时间');
                }
            } 
            
            @sort($data['app']);
            $data['app'] = implode(',', $data['app']);
            
            if ($data['best'] > 0){
                $count = $this->find()->where(['and',['!=','best','0'],['!=','id',$this->id]])->count();
                if ($count >= 2){
                    throw new \Exception('精选房间上限是2个');
                }
            }
            if (isset($data['is_addup'])){
                $data['is_addup'] = Yii::$app->params['config']['is_addup'];
            }else{
                $data['is_addup'] = 0;
            }
            $this->setAttributes($data);
            if (!$this->save()){
                throw new \Exception(current($this->getFirstErrors()));
            }

            //编辑分享内容
            if (!$RoomShare = Share::findOne(['type' => Params::LIVE_SHARE_TYPE, 'obj_id' => $this->room_id])) {
                //编辑以前的房间时,没有相应的分享记录,那么这时候要重新创建一个对象来做插入
                $RoomShare = new Share();
            }
            $RoomShare->setAttributes([
                'obj_id'  => $this->room_id,
                'type'    => Params::LIVE_SHARE_TYPE,
                'pic'     => $data['share_pic'],
                'title'   => $data['share_title'],
                'content' => $data['share_content'],
            ]);
            if (!$RoomShare->save()) {
                throw new \Exception(current($RoomShare->getFirstErrors()));
            }

            $transaction->commit();
            return true;
        }catch (\Exception $e) {
            $transaction->rollBack();
            Yii::$app->session->setFlash('warning', $e->getMessage());
            return false;
        }
        
    }
    
    /**
     * 删除直播间
     * @param type $id
     */
    public function del()
    {
        $transaction = $this->getDb()->beginTransaction();
        try{
            $model = $this;
            
            if (!$model->delete()){
                throw new \Exception(current($model->getFirstErrors()));
            }
            
            if ($model->roomQchannel){
                if (!$model->roomQchannel->delete()){
                    throw new \Exception(current($model->roomQchannel->getFirstErrors()));
                }

                if (!QcloudApiClient::self()->DeleteLVBChannel([$model->roomQchannel->channel_id])){
                    throw new \Exception(QcloudApiClient::self()->error());
                }
            }

            //删除分享
            $delShare = (new Share())->delLivingShare($model->room_id);
            if (!$delShare) {
                throw new \Exception("删除分享失败");
            }
            $transaction->commit();
            return true;
        }catch (\Exception $e) {
            $transaction->rollBack();
            Yii::$app->session->setFlash('warning', $e->getMessage());
            return false;
        }
        
    }
    
    /**
     * 修改频道状态
     * @param type $id
     */
    public function status($status)
    {
        $transaction = $this->getDb()->beginTransaction();
        try{
            $model = $this;
            
            $model->status = $status;
            if ($status == 1){//启用时,直播状态设为未开始
                $model->living = 0;
            }elseif ($status == 0){//禁用时,直播状态设为已结束
                //fixbug 只有正在直播中的房间才会把视频片段设置观看人数  add by yaoxiaofeng|2016.9.29
                if ($model->living == 1 && $model->videoRecording){
                    //停止正在录制的视频
                    $roomNums = \common\models\RoomNums::getRoomNums($model->room_id);
                    $model->videoRecording->audience_num = $roomNums['audience_nums'];
                    $model->videoRecording->like_num = $roomNums['like_nums'];
                    $model->videoRecording->live_end_time = time();
                    $model->videoRecording->save();
                }
                $model->living = 2;
            }
            if (!$model->save(false)){
                throw new \Exception(current($model->getFirstErrors()));
            }
            
            if ($model->roomQchannel){
                if ($status == 1){//启用
                    $ret = QcloudApiClient::self()->StartLVBChannel([$model->roomQchannel->channel_id]);
                }elseif ($status == 0){//禁用
                    /*if ($model->videoRecording){
                        //停止正在录制的视频
                        if ($model->videoRecording->task_id){
                            if (QcloudApiClient::self()->StopRecord($model->roomQchannel->channel_id,$model->videoRecording->task_id)){
                                $model->videoRecording->live_end_time = time();
                                $model->videoRecording->save();
                            }
                        }
                    }*/
                    $ret = QcloudApiClient::self()->StopLVBChannel([$model->roomQchannel->channel_id]);
                }
                
                if (!$ret){
                    throw new \Exception(QcloudApiClient::self()->error());
                }
            }

            $transaction->commit();
            return true;
        }catch (\Exception $e) {
            $transaction->rollBack();
            Yii::$app->session->setFlash('warning', $e->getMessage());
            return false;
        }
        
    }
}