影视CMS系统有哪些
先预览下网站的主要界面,一个列表页,一个详情页:




本着简洁不简单的原则,力求界面尽量简洁,功能尽量实用。 列表页可以根据影片名称、影片介绍、影片分类、演员、导演、地区、语言等搜索影片信息,还可以根据相应字段排序,使用的是yii框架提供的GridView小部件实现的。 详情页即展示一部影片的详情和播放地址。
再次说明:本人不会储存任何影片播放文件,所有的影片信息来自其他网站,仅供说明展示教程功能。
Yii框架的安装见:Yii框架的安装
本系列教程使用的是yii2 高级项目模板自带三个入口。分别是frontend(前台)、backend(后台)、console(命令行入口)。关于yii的多入口、目录结构,基础知识不展开。
安装好yii后,将《从零开始搭建完整的电影全栈系统(一)》中存放影视信息和播放地址的两张表 vod_detail和play_url导入到对应数据库。
使用Yii自带的脚手架工具gii根据数据库生成对应的MVC文件。gii工具号称可以帮我们写代码,很方便就生成了model类,view视图、控制器。
VodDetail:
<?php namespace common\models; use Yii; use yii\helpers\ArrayHelper; /** * This is the model class for table “vod_detail”. * * @property int $id * @property string $url 采集的url * @property string $url_id 采集的url经过加密生成的唯一字符串 * @property string $vod_title 视频名称 * @property string|null $vod_sub_title 视频别名 * @property string|null $vod_blurb 简介 * @property string|null $vod_content 详细介绍 * @property int|null $vod_status 状态 * @property string|null $vod_type 视频分类 * @property string|null $vod_class 扩展分类 * @property string|null $vod_tag * @property string|null $vod_pic_url 图片url * @property string|null $vod_pic_path 图片下载保存路径 * @property string|null $vod_pic_thumb * @property string|null $vod_actor 演员 * @property string|null $vod_director 导演 * @property string|null $vod_writer 编剧 * @property string|null $vod_remarks 影片版本 * @property int|null $vod_pubdate * @property string|null $vod_area 地区 * @property string|null $vod_lang 语言 * @property string|null $vod_year 年代 * @property int|null $vod_hits 总浏览数 * @property int|null $vod_hits_day 一天浏览数 * @property int|null $vod_hits_week 一周浏览数 * @property int|null $vod_hits_month 一月浏览数 * @property int|null $vod_up 顶数 * @property int|null $vod_down 踩数 * @property float|null $vod_score 总评分 * @property int|null $vod_score_all * @property int|null $vod_score_num * @property int|null $vod_create_time 创建时间 * @property int|null $vod_update_time 更新时间 * @property int|null $vod_lately_hit_time 最后浏览时间 */ class VodDetail extends \yii\db\ActiveRecord { /** * {@inheritdoc} */ public static function tableName() { return vod_detail; } /** * {@inheritdoc} */ public function rules() { return [ [[url, url_id, vod_title], required], [[vod_content], string], [[vod_status, vod_pubdate, vod_hits, vod_hits_day, vod_hits_week, vod_hits_month, vod_up, vod_down, vod_score_all, vod_score_num, vod_create_time, vod_update_time, vod_lately_hit_time], integer], [[vod_score], number], [[url], string, max => 500], [[url_id], string, max => 100], [[vod_title, vod_sub_title, vod_blurb, vod_type, vod_class, vod_tag, vod_pic_url, vod_pic_path, vod_pic_thumb, vod_actor, vod_director, vod_writer, vod_remarks, vod_area, vod_lang, vod_year], string, max => 255], [[url_id], unique], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ id => ID, url => Url, url_id => Url ID, vod_title => 影片名称, vod_sub_title => 影片副标题, vod_blurb => Vod Blurb, vod_content => 影片介绍, vod_status => 状态, vod_type => 影片分类, vod_class => 扩展分类, vod_tag => 标签, vod_pic_url => 图片Url链接, vod_pic_path => 图片本地路径, vod_pic_thumb => 缩略图本地路径, vod_actor => 演员, vod_director => 导演, vod_writer => 编剧, vod_remarks => 备注, vod_pubdate => Vod Pubdate, vod_area => 地区, vod_lang => 语言, vod_year => 年代, vod_hits => 浏览次数, vod_hits_day => 日浏览次数, vod_hits_week => 周浏览次数, vod_hits_month => 月浏览次数, vod_up => 顶次数, vod_down => 踩次数, vod_score => 评分, vod_score_all => 总评分, vod_score_num => 评分次数, vod_create_time => 收录时间, vod_update_time => 更新时间, vod_lately_hit_time => 最近浏览时间, ]; } /*** * @return \yii\db\ActiveQuery * 获取视频对应的播放地址 */ public function getPlayurls() { return $this->hasMany(PlayUrl::className(), [url_id => url_id]); //$playurls = $this->hasMany(PlayUrl::className(), [url_id => url_id]); //return ArrayHelper::index($playurls, null, play_from); } }PlayUrl:
<?php namespace common\models; use Yii; /** * This is the model class for table “play_url”. * * @property int $id * @property string|null $play_title * @property string|null $play_from * @property string $play_url * @property string $play_url_aes 将url生成唯一字符串 * @property string $url_id 关联vod_detail url_id * @property int|null $create_time * @property int|null $update_time */ class PlayUrl extends \yii\db\ActiveRecord { /** * {@inheritdoc} */ public static function tableName() { return play_url; } /** * {@inheritdoc} */ public function rules() { return [ [[play_url, play_url_aes, url_id], required], [[create_time, update_time], integer], [[play_title, play_from, play_url], string, max => 255], [[play_url_aes, url_id], string, max => 100], [[play_url_aes], unique], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ id => ID, play_title => Play Title, play_from => Play From, play_url => Play Url, play_url_aes => Play Url Aes, url_id => Url ID, create_time => Create Time, update_time => Update Time, ]; } }VodDetailSearch:
<?php namespace common\models; use yii\base\Model; use yii\data\ActiveDataProvider; use common\models\VodDetail; /** * VodDetailSearch represents the model behind the search form of `common\models\VodDetail`. */ class VodDetailSearch extends VodDetail { /** * {@inheritdoc} */ public function rules() { return [ [[id, vod_status, vod_pubdate, vod_hits, vod_hits_day, vod_hits_week, vod_hits_month, vod_up, vod_down, vod_score_all, vod_score_num, vod_create_time, vod_update_time, vod_lately_hit_time], integer], [[url, url_id, vod_title, vod_sub_title, vod_blurb, vod_content, vod_type, vod_class, vod_tag, vod_pic_url, vod_pic_path, vod_pic_thumb, vod_actor, vod_director, vod_writer, vod_remarks, vod_area, vod_lang, vod_year], safe], [[vod_score], number], ]; } /** * {@inheritdoc} */ public function scenarios() { // bypass scenarios() implementation in the parent class return Model::scenarios(); } /** * Creates data provider instance with search query applied * * @param array $params * * @return ActiveDataProvider */ public function search($params) { $query = VodDetail::find(); // add conditions that should always apply here $dataProvider = new ActiveDataProvider([ query => $query, pagination => [pageSize => 50], sort => [ defaultOrder => [vod_update_time => SORT_DESC], //attributes => [id, title], ], ]); $this->load($params); if (!$this->validate()) { // uncomment the following line if you do not want to return any records when validation fails // $query->where(0=1); return $dataProvider; } // grid filtering conditions $query->andFilterWhere([ id => $this->id, vod_status => $this->vod_status, vod_pubdate => $this->vod_pubdate, vod_hits => $this->vod_hits, vod_hits_day => $this->vod_hits_day, vod_hits_week => $this->vod_hits_week, vod_hits_month => $this->vod_hits_month, vod_up => $this->vod_up, vod_down => $this->vod_down, vod_score => $this->vod_score, vod_score_all => $this->vod_score_all, vod_score_num => $this->vod_score_num, vod_create_time => $this->vod_create_time, vod_update_time => $this->vod_update_time, vod_lately_hit_time => $this->vod_lately_hit_time, ]); $query->andFilterWhere([like, url, $this->url]) ->andFilterWhere([like, url_id, $this->url_id]) ->andFilterWhere([like, vod_title, $this->vod_title]) ->andFilterWhere([like, vod_sub_title, $this->vod_sub_title]) ->andFilterWhere([like, vod_blurb, $this->vod_blurb]) ->andFilterWhere([like, vod_content, $this->vod_content]) ->andFilterWhere([like, vod_type, $this->vod_type]) ->andFilterWhere([like, vod_class, $this->vod_class]) ->andFilterWhere([like, vod_tag, $this->vod_tag]) ->andFilterWhere([like, vod_pic_url, $this->vod_pic_url]) ->andFilterWhere([like, vod_pic_path, $this->vod_pic_path]) ->andFilterWhere([like, vod_pic_thumb, $this->vod_pic_thumb]) ->andFilterWhere([like, vod_actor, $this->vod_actor]) ->andFilterWhere([like, vod_director, $this->vod_director]) ->andFilterWhere([like, vod_writer, $this->vod_writer]) ->andFilterWhere([like, vod_remarks, $this->vod_remarks]) ->andFilterWhere([like, vod_area, $this->vod_area]) ->andFilterWhere([like, vod_lang, $this->vod_lang]) ->andFilterWhere([like, vod_year, $this->vod_year]); return $dataProvider; } }VodDetailController:
<?php namespace frontend\controllers; use Yii; use common\models\VodDetail; use common\models\VodDetailSearch; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; /** * VodDetailController implements the CRUD actions for VodDetail model. */ class VodDetailController extends Controller { /** * {@inheritdoc} */ public function behaviors() { return [ verbs => [ class => VerbFilter::className(), actions => [ delete => [POST], ], ], ]; } /** * Lists all VodDetail models. * @return mixed */ public function actionIndex() { $searchModel = new VodDetailSearch(); $dataProvider = $searchModel->search(Yii::$app->request->queryParams); return $this->render(index, [ searchModel => $searchModel, dataProvider => $dataProvider, ]); } /** * Displays a single VodDetail model. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found */ public function actionView($id) { return $this->render(view, [ model => $this->findModel($id), ]); } /** * Creates a new VodDetail model. * If creation is successful, the browser will be redirected to the view page. * @return mixed */ public function actionCreate() { $model = new VodDetail(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect([view, id => $model->id]); } return $this->render(create, [ model => $model, ]); } /** * Updates an existing VodDetail model. * If update is successful, the browser will be redirected to the view page. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found */ public function actionUpdate($id) { $model = $this->findModel($id); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect([view, id => $model->id]); } return $this->render(update, [ model => $model, ]); } /** * Deletes an existing VodDetail model. * If deletion is successful, the browser will be redirected to the index page. * @param integer $id * @return mixed * @throws NotFoundHttpException if the model cannot be found * @throws \Throwable * @throws \yii\db\StaleObjectException */ public function actionDelete($id) { $this->findModel($id)->delete(); return $this->redirect([index]); } /** * Finds the VodDetail model based on its primary key value. * If the model is not found, a 404 HTTP exception will be thrown. * @param integer $id * @return VodDetail the loaded model * @throws NotFoundHttpException if the model cannot be found */ protected function findModel($id) { if (($model = VodDetail::findOne($id)) !== null) { return $model; } throw new NotFoundHttpException(The requested page does not exist.); } }视图文件:
影视列表:
<?php use yii\helpers\Html; use yii\grid\GridView; /* @var $this yii\web\View */ /* @var $searchModel common\models\VodDetailSearch */ /* @var $dataProvider yii\data\ActiveDataProvider */ $this->title = 影片列表; $this->params[breadcrumbs][] = $this->title; ?> <div class=”vod-detail-index”> <h1><?= Html::encode($this->title) ?></h1> <!–<p>–> <!—-><? //= Html::a(Create Vod Detail, [create], [class => btn btn-success]) ?> <!–</p>–> <?phpecho $this->render(_search, [model => $searchModel]); ?> <?= GridView::widget([ dataProvider => $dataProvider, filterModel => $searchModel, //showHeader => false, showFooter => false, columns => [ //[class => yii\grid\SerialColumn], //id, //url:url, //url_id:url, //vod_title, [attribute => vod_title, value => function ($data) { return Html::a($data->vod_title, [vod-detail/view, id => $data->id], [title => 详情]); }, format => [html]], //vod_sub_title, //vod_blurb, //vod_content:ntext, //vod_status, //vod_type, [attribute => vod_type, value => function ($data) { return Html::a($data->vod_type, [vod-detail/index, VodDetailSearch => [vod_type=>$data->vod_type]], [title => 分类]); }, format => [html]], //vod_class, //vod_tag, //vod_pic_url:url, //vod_pic_path, //vod_pic_thumb, //vod_actor, //vod_director, //vod_writer, vod_remarks, //vod_pubdate, //vod_area, //vod_lang, //vod_year, [attribute => vod_year, value => function ($data) { return Html::a($data->vod_year, [vod-detail/index, VodDetailSearch => [vod_year=>$data->vod_year]], [title => 年代]); }, format => [html]], //vod_hits, //vod_hits_day, //vod_hits_week, //vod_hits_month, //vod_up, //vod_down, //vod_score, //vod_score_all, //vod_score_num, //vod_create_time:datetime, //vod_update_time:datetime, [attribute => vod_update_time, format => [date, php:Y-m-d H:i:s]], //vod_lately_hit_time:datetime, /*[ class => yii\grid\ActionColumn, template => {view}, ],*/ ], pager => [ //options => [class => hidden]//关闭分页(默认开启) /* 默认不显示的按钮设置 */ firstPageLabel => 首页, prevPageLabel => 上一页, nextPageLabel => 下一页, lastPageLabel => 尾页 ] ]); ?> </div>影视详情:
<?php use yii\helpers\ArrayHelper; use yii\helpers\Html; use yii\helpers\Url; use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model common\models\VodDetail */ $this->title = $model->vod_title; $this->params[breadcrumbs][] = [label => 影片列表, url => [index]]; $this->params[breadcrumbs][] = $this->title; \yii\web\YiiAsset::register($this); $playurlsList = ArrayHelper::index($model->playurls, null, play_from); ?> <div class=”stui-pannel clearfix”> <div class=”stui-content clearfix”> <div class=”stui-content__thumb”> <?= Html::tag(a, Html::img($model->vod_pic_url, [class => img-responsive, alt => $model->vod_title]), [class => thumb, href => Url::toRoute([vod-detail/view, id => $model->id]), title => $model->vod_title]) ?> <p class=”margin-0 text-center hidden-xs”><a class=”copy_btn text-muted” href=”javascript:;” data-text=<?= Url::to(, true) ?>>复制图片地址</a> </p> </div> <div class=”stui-content__detail”> <?= Html::tag(h1, $model->vod_title . Html::tag(small, $model->vod_score, [class => text-red]), [class => title]) ?> <?= Html::tag(p, Html::tag(span, 别名: . $model->vod_sub_title, [class => text-muted hidden-xs]), [class => data hidden-xs]) ?> <?= Html::tag(p, Html::tag(span, 地区: . $model->vod_area, [class => text-muted]), [class => data hidden-md hidden-lg hidden-sm]) ?> <p class=”data”> <?= Html::tag(span, 状态:, [class => text-muted]) ?> <?= Html::tag(span, $model->vod_remarks, [class => text-red]) ?> <span class=”split-line hidden-xs”></span> <span class=”text-muted hidden-xs”>更新时间:</span><?= Html::tag(span, date(Y-m-d H:i:s, $model->vod_update_time)) ?> </p> <p class=”data”><span class=”text-muted”>主演:</span><?php echo $model->vod_actor ?></p> <p class=”data”><span class=”text-muted”>导演:</span><?php echo $model->vod_director ?></p> <p class=”data hidden-xs”> <span class=”text-muted”>分类:</span><?php echo $model->vod_type ?> <span class=”split-line”></span> <!–<span class=”text-muted”>扩展:</span><a href=”/index.php/vod/search/class/%E6%AC%A7%E7%BE%8E%E5%89%A7.html” target=”_blank”>欧美剧</a> –> <span class=”split-line”></span> <span class=”text-muted”>地区:</span><?php echo $model->vod_area ?> <span class=”split-line”></span> <span class=”text-muted”>年份:</span><?php echo $model->vod_year ?> </p> <p class=”data hidden-xs”> <span class=”text-muted”>语言:</span><?php echo $model->vod_lang ?> <span class=”split-line”></span> <!–<span class=”text-muted”>集数:</span>0 <span class=”split-line”></span> <span class=”text-muted”>时长:</span> <span class=”split-line”></span> <span class=”text-muted”>豆瓣ID:</span>0 </p>–> <p class=”data hidden-xs”> <span class=”text-muted”>TAG:</span> <span class=”split-line”><?php echo $model->vod_tag ?></span> </p> </div> </div> </div> <div class=”stui-pannel clearfix” id=”desc”> <div class=”stui-pannel__head clearfix”> <h3 class=”title”>剧情介绍</h3> </div> <div class=”stui-content__desc col-pd clearfix”> <?= nl2br($model->vod_content); ?> </div> </div> <?php foreach ($playurlsList as $key => $playurls): ?> <div class=”stui-pannel clearfix” id=”playlist”> <div class=”stui-pannel__head clearfix”> <span class=”more text-muted pull-right hidden-xs”>无需安装任何插件</span> <h3 class=”title”> 播放类型:<?php echo $key ?></h3> </div> <ul class=”stui-content__playlist clearfix”> <?php foreach ($playurls as $key => $playurl): ?> <li class=”list-group-item”> <span class=”badge”>用App打开</span> <a href=”javascript:;” class=”copy_text”><?= $playurl->play_title ?><span class=”hidden-xs”><?= $. $playurl->play_url ?></span></a> </li> <!–<li> <a class=”text-muted pull-right” href=”/index.php/vod/play/id/43801/sid/1/nid/1.html”> ></a> <a href=”javascript:;” class=”copy_text”><?/*= $playurl->play_title */?><span class=”hidden-xs”><?/*= $. $playurl->play_url */?></span></a> </li>–> <?php endforeach; ?> <!– end 播放地址 –> </ul> <div class=”stui-pannel__foot clearfix”> <span class=”text-muted pull-right hidden-xs”>tips:点击链接可以复制哦</span> <a class=”copy_checked text-red” href=”javascript:;”>复制全部</a> </div> </div> <?php endforeach; ?>别忘了注入自定义的js和css文件。
整个WEB网站的搭建自行代码写的最多的就是影视详情页的模板。列表页排序、搜索、分页是自定义yii自带的GridView小部件实现的。
对Yii基础知识不熟悉的同学可以自行学习。 整理完成后代码发布与github。
欢迎各位大佬入裙交流:
苹果cms站群