From e6e78674150c0b86e27ad3a917998a7c1630367a Mon Sep 17 00:00:00 2001 From: dengbw Date: Thu, 17 Feb 2022 11:15:55 +0800 Subject: [PATCH] admin_polyv_217 --- admin/controllers/app/licheb/Main.php | 9 + admin/controllers/live/Polyv.php | 338 ++++++++++++++++++ admin/views/live/polyv/lists.php | 170 +++++++++ admin/views/live/polyv/lists_viewlog.php | 169 +++++++++ common/libraries/{Polyv.php => PolyvApi.php} | 55 ++- .../models/live/Live_polyv_session_model.php | 17 + .../models/live/Live_polyv_viewlog_model.php | 17 + 7 files changed, 764 insertions(+), 11 deletions(-) create mode 100644 admin/controllers/live/Polyv.php create mode 100644 admin/views/live/polyv/lists.php create mode 100644 admin/views/live/polyv/lists_viewlog.php rename common/libraries/{Polyv.php => PolyvApi.php} (67%) create mode 100644 common/models/live/Live_polyv_session_model.php create mode 100644 common/models/live/Live_polyv_viewlog_model.php diff --git a/admin/controllers/app/licheb/Main.php b/admin/controllers/app/licheb/Main.php index 815fbcc8..65e3b085 100644 --- a/admin/controllers/app/licheb/Main.php +++ b/admin/controllers/app/licheb/Main.php @@ -19,6 +19,7 @@ class Main extends HD_Controller $this->load->model('app/material/Material_template_model', 'mdTemplate'); $this->load->model('app/material/Material_biz_model', 'mdMaterialBiz'); $this->load->model('topics/topics_model', 'mdTopics'); + $this->load->model('live/Live_polyv_session_model', 'mdPolyvSession'); } public function index() @@ -80,6 +81,14 @@ class Main extends HD_Controller array('name' => '查看详情', 'url' => '/app/licheb/sytactivity'), ), ); + $value = $this->mdPolyvSession->count(); + $list[] = array( + 'title' => '保利威直播-场次报表', + 'value' => $value, + 'btns' => array( + array('name' => '查看详情', 'url' => '/live/polyv'), + ), + ); $conditions[] = array('icon' => 'am-icon-user', 'list' => $list); /*小程序设置 end*/ diff --git a/admin/controllers/live/Polyv.php b/admin/controllers/live/Polyv.php new file mode 100644 index 00000000..1ecf2ce4 --- /dev/null +++ b/admin/controllers/live/Polyv.php @@ -0,0 +1,338 @@ +load->model('live/Live_polyv_session_model', 'mdPolyvSession'); + $this->load->model('live/Live_polyv_viewlog_model', 'mdPolyvViewlog'); + } + + public function index() + { + return $this->lists(); + } + + public function lists() + { + $params = $this->input->get(); + $params['page'] = $params['page'] ? intval($params['page']) : 1; + $params['size'] = $params['size'] ? intval($params['size']) : 20; + $lists = []; + $where = ['channelId' => $this->channelId]; + if ($params['sessionId']) { + $where["sessionId"] = $params['sessionId']; + } + if ($params['time']) { + $time = explode(' ~ ', $params['time']); + $time[0] && $where["startTime>="] = strtotime($time[0] . ' 00:00:00') * 1000; + $time[1] && $where["endTime<="] = strtotime($time[1] . ' 23:59:59') * 1000; + } + $total = $this->mdPolyvSession->count($where); + if ($total) { + $res = $this->mdPolyvSession->select($where, "startTime desc", $params['page'], $params['size']); + foreach ($res as $key => $value) { + $setValue = $value; + $setValue['duration'] = $value['duration'] ? ceil($value['duration'] / 60) : '0'; + $setValue['totalPlayDuration'] = $value['totalPlayDuration'] ? ceil($value['totalPlayDuration'] / 60) : '0'; + $setValue['startTime'] = $value['startTime'] ? date('Y-m-d H:i:s', $value['startTime'] / 1000) : ''; + $setValue['endTime'] = $value['endTime'] ? date('Y-m-d H:i:s', $value['endTime'] / 1000) : ''; + $setValue['viewlog_time'] = $value['viewlog_time'] != '0000-00-00 00:00:00' + ? date('Y-m-d H:i', strtotime($value['viewlog_time'])) : '未同步'; + $setValue['session_time'] = date('Y-m-d H:i', strtotime($value['session_time'])); + $lists[] = $setValue; + } + } + $this->data['pager'] = array('count' => ceil($total / $params['size']), 'curr' => $params['page'], 'totle' => $total); + $this->data['lists'] = $lists; + $this->data['params'] = $params; + $this->data['_title'] = "保利威频道({$this->channelId})_场次报表"; + $this->show_view('live/polyv/lists', true); + } + + public function lists_viewlog() + { + $params = $this->input->get(); + if (!$params['sessionId']) { + return $this->show_json(SYS_CODE_FAIL, '场次ID不能为空!'); + } + $menuAry = []; + $re_session = $this->mdPolyvSession->get(['channelId' => $this->channelId, 'sessionId' => $params['sessionId']]); + if (!$re_session) { + return $this->show_json(SYS_CODE_FAIL, '无此场次数据!'); + } + $re_session['startTime'] = $re_session['startTime'] ? date('Y-m-d H:i:s', $re_session['startTime'] / 1000) : ''; + if ($params['param3'] == 'live') { + $re_session['duration'] = $re_session['duration'] ? ceil($re_session['duration'] / 60) : '0'; + $re_session['totalPlayDuration'] = $re_session['totalPlayDuration'] ? ceil($re_session['totalPlayDuration'] / 60) : '0'; + $menuAry = [['title' => '直播时长(分钟)', 'value' => $re_session['duration'], 'tag' => '讲师该场直播直播时间'] + , ['title' => '观看人数', 'value' => $re_session['liveUV'], 'tag' => '观看人数为观看用户总数,计算方式为观看记录根据用户id去重的条目数'] + , ['title' => '观看次数', 'value' => $re_session['livePV'], 'tag' => '观看次数为观看记录条目数,用户刷新页面或者离开再进入直播,记为2条观看记录'] + , ['title' => '观看时长', 'value' => $re_session['totalPlayDuration'], 'tag' => '观看时长是根据每条观看记录向上取整(不足1分钟按1分钟计算),最后再相加后的结果。例如:单条观看记录时长为1分36秒,统计时会计算为2分钟。'] + , ['title' => '人均观看时长', 'value' => $re_session['totalPlayDuration'] / $re_session['liveUV'], 'tag' => '人均观看时长=累计观看时长/观看人数,单位:分钟'] + ]; + } else if ($params['param3'] == 'vod') { + $re_sum = $this->mdPolyvViewlog->sum('stayDuration', ['param3' => 'vod', 'channelId' => $this->channelId, 'sessionId' => $params['sessionId']]); + $duration = $re_sum['stayDuration'] ? ceil($re_sum['stayDuration'] / 60) : '0'; + $menuAry = [['title' => '回看时长(分钟)', 'value' => $duration, 'tag' => '观看时长是根据每条观看记录向上取整(不足1分钟按1分钟计算),最后再相加后的结果。例如:单条观看记录时长为1分36秒,统计时会计算为2分钟。'] + , ['title' => '回看人数', 'value' => $re_session['playbackUV'], 'tag' => '回看人数为观看次数针对userid和时间去重,如果一个人连续2天都有观看,记为1次'] + , ['title' => '回看次数', 'value' => $re_session['playbackPV'], 'tag' => '回看次数为该场次暂存列表和回放列表观看记录汇总'] + ]; + } + $results = $this->dataSelect($params); + $this->data['lists'] = $results['lists']; + $this->data['params'] = $results['params']; + $this->data['pager'] = $results['pager']; + $this->data['_title'] = $results['_title']; + $this->data['menuAry'] = $menuAry; + $this->data['info'] = $re_session; + $this->show_view('live/polyv/lists_viewlog', true); + } + + private function dataSelect($params) + { + $params['page'] = $params['page'] ? intval($params['page']) : 1; + $params['size'] = $params['size'] ? intval($params['size']) : 20; + $params['param3'] = $params['param3'] ? $params['param3'] : 'live'; + $params['merge'] = $params['merge'] ? $params['merge'] : ''; + $lists = $menuAry = []; + $where = ['channelId' => $this->channelId, 'sessionId' => $params['sessionId'], 'param3' => $params['param3']]; + if ($params['merge']) { + $total = $this->mdPolyvViewlog->count($where, 'param1'); + } else { + $total = $this->mdPolyvViewlog->count($where); + } + if ($total) { + $fileds = ''; + $params['size'] == 10000 && $fileds = 'param3,city,isMobile,referer,param4,param5,sessionId,';//导出 + if ($params['merge']) { + $fileds .= 'param1,param2,createdTime,sum(playDuration) as playDuration,browser,ipAddress,province'; + $res = $this->mdPolyvViewlog->select_groupby('param1', $where, "createdTime desc", $params['page'], $params['size'], $fileds); + } else { + $fileds .= 'param1,param2,createdTime,playDuration,browser,ipAddress,province'; + $res = $this->mdPolyvViewlog->select($where, "createdTime desc", $params['page'], $params['size'], $fileds); + } + foreach ($res as $key => $value) { + $setValue = $value; + $setValue['createdTime'] = date('Y-m-d H:i:s', $value['createdTime'] / 1000); + $playDuration = '0'; + if ($value['playDuration']) { + $format = $value['playDuration'] >= 3600 || $params['size'] == 10000 ? 'H:i:s' : 'i:s';//大1小时 + $playDuration = gmdate($format, $value['playDuration']); + } + $setValue['playDuration'] = $playDuration; + $lists[] = $setValue; + } + } + $data['pager'] = array('count' => ceil($total / $params['size']), 'curr' => $params['page'], 'totle' => $total); + $data['lists'] = $lists; + $data['params'] = $params; + $data['_title'] = "观看日志统计"; + return $data; + } + + /** + * Notes:同步保利威分页查询频道直播观看详情数据 + * Created on: 2022/2/14 14:38 + * Created by: dengbw + * @return bool + */ + public function api_viewlog() + { + $sessionIds = $this->input->post('sessionid'); + $params['sessionIds'] = $sessionIds; + if (!$params['sessionIds']) { + return $this->show_json(SYS_CODE_FAIL, '场次ID不能为空!'); + } + $re_session = $this->mdPolyvSession->get(['channelId' => $this->channelId, 'sessionId' => $params['sessionIds']]); + if (!$re_session) { + return $this->show_json(SYS_CODE_FAIL, '无此场次数据!'); + } + if ($re_session['viewlog_time'] != '0000-00-00 00:00:00') { + $startTime = strtotime($re_session['viewlog_time']); + } else { + $startTime = $re_session['startTime'] / 1000; + } + $endTime = strtotime(date('Y-m-d H:i:s')); + //不同月份时开始取本月第1天 + if (date('m', $startTime) != date('m', $endTime)) { + $startTime = strtotime(date('Y-m', time()) . '-01 00:00:00'); + } + $params['startTime'] = $startTime * 1000; + $params['endTime'] = $endTime * 1000; + $params['page'] = 1; + $results = $this->getViewLog($params); +// $this->data['params'] = $params; +// $this->data['results'] = $results; + $message = $results['message']; + if ($results['status'] == 'success') { + $i = 10; + while (($i--) > 0) { + if ($results['status'] == 'success' && !$results['lastPage'] + && $results['pageNumber'] != $results['nextPageNumber']) { + $params['page'] = $results['nextPageNumber']; + $results = $this->getViewLog($params); + continue; + } else { + break; + } + } + //同步观看数据时间 + $this->mdPolyvSession->update(['viewlog_time' => date('Y-m-d H:i:s', $endTime)], ['id' => $re_session['id']]); + return $this->show_json(SYS_CODE_SUCCESS, '操作成功'); + } else { + return $this->show_json(SYS_CODE_FAIL, $message); + } + } + + private function getViewLog($params) + { + $this->load->library('PolyvApi'); + $polyv = new PolyvApi(['channel_id' => $this->channelId]); + $results = $polyv->getViewLog($params); + if ($results['status'] == 'success') { + $addData = []; + foreach ($results['data']['contents'] as $key => $value) { + $re = $this->mdPolyvViewlog->get(['playId' => $value['playId']]); + $data = [ + 'channelId' => $value['channelId'], 'sessionId' => $value['sessionId'], 'playId' => $value['playId'], + 'userId' => $value['userId'], 'playDuration' => $value['playDuration'], 'stayDuration' => $value['stayDuration'], + 'flowSize' => $value['flowSize'], 'param1' => $value['param1'], 'param2' => $value['param2'], + 'param3' => $value['param3'], 'param4' => $value['param4'], 'param5' => $value['param5'], 'ptype' => $value['ptype'], + 'ipAddress' => $value['ipAddress'], 'country' => $value['country'], 'province' => $value['province'], + 'city' => $value['city'], 'isp' => $value['isp'], 'referer' => $value['referer'], 'userAgent' => $value['userAgent'], + 'operatingSystem' => $value['operatingSystem'], 'browser' => $value['browser'], 'isMobile' => $value['isMobile'], + 'currentDay' => $value['currentDay'], 'createdTime' => $value['createdTime'], 'lastModified' => $value['lastModified'], + ]; + if ($re) {//同步更新数据 + $this->mdPolyvViewlog->update($data, ['id' => $re['id']]); + } else {//新增 + $data['c_time'] = time(); + $addData[] = $data; + } + } + if ($addData && count($addData)) {//新增数据 + $this->mdPolyvViewlog->add_batch($addData); + } + } + return $results; + } + + /** + * Notes:同步保利威频道多场次概览统计数据 + * Created on: 2022/2/11 16:50 + * Created by: dengbw + * @return bool + */ + public function api_session() + { + $params = $this->input->post(); + $where = []; + $params['sessionId'] && $where['sessionIds'] = $params['sessionId']; + if ($params['time']) { + $time = explode(' ~ ', $params['time']); + $time[0] && $where["startTime"] = strtotime($time[0] . ' 00:00:00') * 1000; + $time[1] && $where["endTime"] = strtotime($time[1] . ' 23:59:59') * 1000; + } + $this->load->library('PolyvApi'); + $polyv = new PolyvApi(['channel_id' => $this->channelId]); + $results = $polyv->getSessionStats($where); + if ($results['status'] == 'success') { + foreach ($results['data']['list'] as $key => $value) { + $re = $this->mdPolyvSession->get(['channelId' => $this->channelId, 'sessionId' => $value['sessionId']]); + $data = [ + 'channelId' => $value['channelId'], 'sessionId' => $value['sessionId'], 'name' => $value['name'], + 'startTime' => $value['startTime'], 'endTime' => $value['endTime'], 'duration' => $value['duration'], + 'liveUV' => $value['liveUV'], 'livePV' => $value['livePV'], 'playbackUV' => $value['playbackUV'], + 'playbackPV' => $value['playbackPV'], 'totalPlayDuration' => $value['totalPlayDuration'], + 'session_time' => date('Y-m-d H:i:s'), + ]; + if ($re) {//同步更新数据 + $this->mdPolyvSession->update($data, ['id' => $re['id']]); + } else {//新增 + $data['c_time'] = time(); + $this->mdPolyvSession->add($data); + } + } + return $this->show_json(SYS_CODE_SUCCESS, '操作成功'); + } else { + return $this->show_json(SYS_CODE_FAIL, $results['message']); + } + } + + public function get() + { + } + + public function add() + { + } + + public function edit() + { + } + + public function del() + { + } + + + public function batch() + { + } + + public function export() + { + $params = $this->input->get(); + $params['page'] = 1; + $params['size'] = 10000; + $data = $indexs = array(); + $res = $this->dataSelect($params); + $fileName = $res['_title']; + foreach ($res['lists'] as $key => $value) { + $temp['playDuration'] = $value['playDuration']; + $temp['param1'] = $value['param1']; + $temp['param2'] = $value['param2']; + $temp['param3'] = $value['param3'] == 'live' ? '直播' : '回放'; + $temp['createdTime'] = $value['createdTime']; + $temp['ipAddress'] = $value['ipAddress']; + $temp['province'] = $value['province']; + $temp['city'] = $value['city']; + $temp['browser'] = $value['browser']; + $temp['isMobile'] = $value['isMobile'] == 'Y' ? '是' : '否'; + $temp['referer'] = $value['referer']; + $temp['param4'] = $value['param4']; + $temp['param5'] = $value['param5']; + $temp['sessionId'] = $value['sessionId']; + $data[] = $temp; + } + $indexs = [ + 'playDuration' => '观看时长', + 'param1' => '用户ID', + 'param2' => '昵称', + 'param3' => '观看类型', + 'createdTime' => '开始时间', + "ipAddress" => "观众IP", + "province" => "地区", + "city" => "城市", + "browser" => "浏览器类型", + "isMobile" => "是否移动端", + "referer" => "观看地址", + "param4" => "param4", + "param5" => "param5", + "sessionId" => "场次ID", + ]; + array_unshift($data, $indexs); + $this->load->library('excel'); + $this->excel->out_csv($data, $indexs, $fileName . "_" . date('YmdHis')); + } +} \ No newline at end of file diff --git a/admin/views/live/polyv/lists.php b/admin/views/live/polyv/lists.php new file mode 100644 index 00000000..e13be552 --- /dev/null +++ b/admin/views/live/polyv/lists.php @@ -0,0 +1,170 @@ +
+ +
+
共有条数据
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
场次ID名称开始时间结束时间直播时长观看人数观看次数观看时长 + 回看人数回看次数
+ 同步场次数据:     + 同步观看数据: + + 查看详情 + 同步观看数据 +
+
+
+
+
+
+ +
+
+
+ diff --git a/admin/views/live/polyv/lists_viewlog.php b/admin/views/live/polyv/lists_viewlog.php new file mode 100644 index 00000000..4f86239b --- /dev/null +++ b/admin/views/live/polyv/lists_viewlog.php @@ -0,0 +1,169 @@ + + + + + + + + +
同步观看数据
直播开始时间 : | 场次id:(同步观看数据时间:
+ +
+
+ +
+ +
+
+ $value) { ?> +
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+ + + + + +
> 合并同一用户 + 观看数据常见问题 +    + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
UserId昵称观看开始时间时长观看终端IP地区
+
+
+
+
+
+ +
+
+
+ + \ No newline at end of file diff --git a/common/libraries/Polyv.php b/common/libraries/PolyvApi.php similarity index 67% rename from common/libraries/Polyv.php rename to common/libraries/PolyvApi.php index 130e3348..a766e5cb 100644 --- a/common/libraries/Polyv.php +++ b/common/libraries/PolyvApi.php @@ -5,13 +5,13 @@ * Created by: dengbw */ -class Polyv +class PolyvApi { protected $url = "http://api.polyv.net/live"; - protected $user_id = "549cf353c6";//2a3b848cd4 - protected $app_id = "fr0myucldj";//g45uep0s6v - protected $app_secret = "4919b95df21e4afd80fe14ae8a722b1c";//447d5ce803d84f599794a3274177f796 - protected $channel_id = "2005999";//2797712 + protected $user_id = "2a3b848cd4";//549cf353c6 + protected $app_id = "g45uep0s6v";//fr0myucldj + protected $app_secret = "447d5ce803d84f599794a3274177f796";//4919b95df21e4afd80fe14ae8a722b1c + protected $channel_id = "2810581";//2005999 protected $timestamp;//时间戳 public function __construct($param = []) @@ -23,6 +23,35 @@ class Polyv $this->timestamp = time() * 1000; } + /** + * Notes:分页查询频道直播观看详情数据 + * https://help.polyv.net/index.html#/live/api/channel/viewdata/viewlog_page + * Created on: 2022/2/11 16:52 + * Created by: dengbw + * @param array $params + * @return bool|string + */ + function getViewLog($params = []) + { + $params_sign = array( + 'appId' => $this->app_id,//账号appid + 'timestamp' => $this->timestamp,//当前13位毫秒级时间戳,3分钟内有效 + ); + $params['sessionIds'] && $params_sign['sessionIds'] = $params['sessionIds'];//场次ID, 多个场次使用,分隔 + $params['page'] && $params_sign['page'] = $params['page'];//当前页码,默认为1 + $params['pageSize'] && $params_sign['pageSize'] = $params['pageSize'];//每页显示的数据条数,默认每页显示1000条数据 + $params['currentDay'] && $params_sign['currentDay'] = $params['currentDay'];//查询日期,格式:yyyy-MM-dd + $params['startTime'] && $params_sign['startTime'] = $params['startTime'];//查询开始时间,为13位毫秒级时间戳 + $params['endTime'] && $params_sign['endTime'] = $params['endTime'];//查询结束时间,13位毫秒级时间戳 + $params['param1'] && $params_sign['param1'] = $params['param1'];//观看用户ID,默认查询全部 + $params['param2'] && $params_sign['param2'] = $params['param2'];//观看用户昵称,默认查询全部 + $params['param3'] && $params_sign['param3'] = $params['param3'];//观看日志类型,默认查询全部vod:观看回放 live:直播 + $sign = $this->getSign($params_sign); + $parts = http_build_query($params_sign); + $url = $this->url . "/v2/statistics/{$this->channel_id}/viewlog?{$parts}&sign={$sign}"; + return $this->curlGet($url); + } + /** * Notes:查询频道多场次概览统计数据 * https://help.polyv.net/index.html#/live/api/channel/viewdata/get_session_stats @@ -34,14 +63,14 @@ class Polyv function getSessionStats($params = []) { $params_sign = array( - 'appId' => $this->app_id, - 'timestamp' => $this->timestamp, + 'appId' => $this->app_id,//账号appid + 'timestamp' => $this->timestamp,//当前13位毫秒级时间戳,3分钟内有效 'userId' => $this->user_id, - 'channelId' => $params['channelId'] ? $params['channelId'] : $this->channel_id, + 'channelId' => $params['channelId'] ? $params['channelId'] : $this->channel_id,//频道号 ); - $params['sessionIds'] && $params_sign['sessionIds'] = $params['sessionIds']; - $params['startTime'] && $params_sign['startTime'] = $params['startTime']; - $params['endTime'] && $params_sign['endTime'] = $params['endTime']; + $params['sessionIds'] && $params_sign['sessionIds'] = $params['sessionIds']; //场次ID,多个场次使用逗号分隔,如:fw82mayhuy,fvipafupmh,场次ID和直播开始结束时间必填一项,场次ID和直播开始结束时间同时存在时,使用场次ID进行查询 + $params['startTime'] && $params_sign['startTime'] = $params['startTime'];//直播开始时间,13位毫秒级时间戳,开始时间和结束时间相隔不可以超过30天 + $params['endTime'] && $params_sign['endTime'] = $params['endTime'];//直播结束时间,13位毫秒级时间戳,场次ID和直播开始结束时间必填一项 $sign = $this->getSign($params_sign); $parts = http_build_query($params_sign); $url = $this->url . "/v3/channel/statistics/get-session-stats?{$parts}&sign={$sign}"; @@ -151,6 +180,8 @@ class Polyv curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 360); $data = curl_exec($ch); curl_close($ch); + $data = trim($data, chr(239) . chr(187) . chr(191)); + $data = json_decode($data, true); return $data; } @@ -182,6 +213,8 @@ class Polyv curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); + $data = trim($data, chr(239) . chr(187) . chr(191)); + $data = json_decode($data, true); return $data; } } diff --git a/common/models/live/Live_polyv_session_model.php b/common/models/live/Live_polyv_session_model.php new file mode 100644 index 00000000..d9306c39 --- /dev/null +++ b/common/models/live/Live_polyv_session_model.php @@ -0,0 +1,17 @@ +table_name, 'default'); + } +} \ No newline at end of file diff --git a/common/models/live/Live_polyv_viewlog_model.php b/common/models/live/Live_polyv_viewlog_model.php new file mode 100644 index 00000000..06f8fa2d --- /dev/null +++ b/common/models/live/Live_polyv_viewlog_model.php @@ -0,0 +1,17 @@ +table_name, 'default'); + } +} \ No newline at end of file