CheckAttachController.class.php 8.88 KB
<?php
/**
 * Created by PhpStorm.
 * User: liyifei2012it
 * Date: 17/4/13
 * Time: 11:38
 */
namespace Frontend\Controller\Callback;

use Think\Log;
use VcySDK\Service;
use VcySDK\Cron;
use VcySDK\FileConvert;
use Common\Common\Constant;
use Common\Common\NewsHelper;
use Common\Service\ArticleService;
use Common\Service\AttachService;
use Common\Service\TaskService;
use Common\Service\ClassService;

class CheckAttachController extends AbstractController
{
    /**
     * 附件转换计划任务
     * @author zhonglei
     */
    public function Index()
    {
        Log::record(sprintf('---%s %s CheckAttach START---', QY_DOMAIN, APP_IDENTIFIER), Log::INFO);

        $article_id = I('get.article_id', 0, 'intval');
        $cron_id = I('get.cron_id', '', 'trim');
        if (empty($article_id)) {
            $this->_exit();
        }

        $taskServ = new TaskService();
        $task = $taskServ->get_by_conds(['article_id' => $article_id]);
        // 本地未找到任务,删除UC的任务后退出
        if (empty($task)) {
            if (!empty($cron_id)) {
                $this->_delTask($article_id, $cron_id);
            }
            Log::record("not found task, article_id: {$article_id}", Log::INFO);
            $this->_exit();
        }

        $cron_id = $task['cron_id'];
        $articleServ = new ArticleService();
        $article = $articleServ->get($article_id);

        // 未找到新闻,删除计划任务
        if (empty($article)) {
            Log::record("not found article, article_id: {$article_id}", Log::INFO);
            $this->_delTask($article_id, $cron_id);
        }

        // 获取附件
        $attachServ = new AttachService();
        $list = $attachServ->list_by_conds(['article_id' => $article_id]);
        $attachs = $attachServ->formatDBData($list);

        // 未找到附件,删除计划任务
        if (empty($attachs)) {
            Log::record("not found attach, article_id: {$article_id}", Log::INFO);
            $this->_delTask($article_id, $cron_id);
        }

        $convertServ = new FileConvert(Service::instance());

        $at_convert_status = [];
        foreach ($attachs as $k => $data) {
            // 仅处理文件 (视频现在必须转码完成后才能提交,因此不会在保存后进行转码)
            if (!in_array($k, [Constant::ATTACH_TYPE_FILE])) {
                continue;
            }

            foreach ($data as $attach) {
                // 已完成
                if (!empty($attach['at_convert_url'])) {
                    continue;
                }

                $at_convert_url = '';
                // 默认转码中
                $at_convert_status[$attach['at_id']] = Constant::FILE_STATUS_CONVERT;

                switch ($k) {
                    // 视频 (视频现在必须转码完成后才能提交,因此不会在保存后进行转码;但此段代码暂时保留)
                    case Constant::ATTACH_TYPE_VIDEO:
                        $result = $convertServ->getVodPlayUrl($attach['at_id']);
                        if (is_array($result) && (isset($result['url']) || isset($result['hd']))) {
                            $at_convert_url = str_replace('http://', '//', (!empty($result['hd']) ? $result['hd'] : $result['url']));
                            $at_convert_url = str_replace('https://', '//', $at_convert_url);

                            // 视频封面地址
                            $at_cover_url = str_replace('http://', '//', $result['coverUrl']);
                            $at_cover_url = str_replace('https://', '//', $at_cover_url);

                            // 转码成功
                            $at_convert_status[$attach['at_id']] = Constant::FILE_STATUS_NORMAL;
                        }
                        break;

                    // 文件
                    case Constant::ATTACH_TYPE_FILE:
                        $result = $convertServ->get($attach['at_id']);
                        if (is_array($result) && isset($result['caConvertStatus'])) {
                            // 转码成功
                            if ($result['caConvertStatus'] == FileConvert::CONVERT_STATUS_SUCCESS) {
                                $at_convert_url = $result['caAttachment'];
                                $at_convert_status[$attach['at_id']] = Constant::FILE_STATUS_NORMAL;
                            }

                            // 转码失败(状态不是:待处理、转码中、成功,即为失败)
                            $normalStatus = [
                                FileConvert::CONVERT_STATUS_WATTING,
                                FileConvert::CONVERT_STATUS_ING,
                                FileConvert::CONVERT_STATUS_SUCCESS,
                            ];
                            if (!in_array($result['caConvertStatus'], $normalStatus)) {
                                $at_convert_status[$attach['at_id']] = Constant::FILE_STATUS_FAIL;
                            }
                        }
                        break;
                }

                // 更新文件转码地址
                if (!empty($at_convert_url)) {
                    $attachServ->update(
                        $attach['attach_id'],
                        [
                            'at_convert_url' => $at_convert_url,
                            'at_cover_url' => isset($at_cover_url) ? $at_cover_url : ''
                        ]
                    );
                    Log::record("convert success, attach_id: {$attach['attach_id']}, at_convert_url: {$at_convert_url}", Log::INFO);
                }
            }
        }

        // 所有需转码文件的转码状态
        $convert_status = array_unique(array_values($at_convert_status));

        // 新闻转码失败(将新闻发布状态改为"草稿",文件转码状态改为"转码失败")
        if (in_array(Constant::FILE_STATUS_FAIL, $convert_status)) {
            $articleServ->update($article_id, ['news_status' => Constant::NEWS_STATUS_DRAFT, 'convert_status' => Constant::FILE_STATUS_FAIL]);
            Log::record("update article news_status, article_id: {$article_id}", Log::INFO);
            // 结束任务
            $this->_delTask($article_id, $cron_id);
        }

        // 新闻转码成功
        if (count($convert_status) == 1 && in_array(Constant::FILE_STATUS_NORMAL, $convert_status)) {
            if ($article['news_status'] == Constant::NEWS_STATUS_READY_SEND) {
                // 修改文件发布状态、转码状态

                // 修改转码状态为已转码,当发布状态不为定时发布时修改为已发布,否则不做修改
                $updateData = ['convert_status' => Constant::FILE_STATUS_NORMAL];
                if ($article['news_status'] != Constant::NEWS_STATUS_TIMING_RELEASE) {
                    $updateData['news_status'] = Constant::NEWS_STATUS_SEND;
                }
                $articleServ->update($article_id, $updateData);
                Log::record("update article news_status, article_id: {$article_id}", Log::INFO);

                // 当为发布时
                if (isset($updateData['news_status'])) {
                    // 获取顶级分类名称
                    $classServ = new ClassService();
                    $class = $classServ->getTopClass($article['class_id']);
                    $article['class_name'] = $class['class_name'];

                    // 发送未读提醒
                    if ($article['is_notice'] == Constant::NEWS_IS_NOTICE_TRUE) {
                        $newsHelper = &NewsHelper::instance();
                        list($uids_all, $uids_read, $uids_unread) = $newsHelper->getReadData($article_id);
                        $newsHelper->sendUnreadMsg($uids_unread, $article);
                    }

                    // RPC推送到运营中心
                    if ($article['is_recommend'] == Constant::NEWS_IS_RECOMMEND_TRUE) {
                        $articleServ->addNewsRpc($article_id, []);
                    }
                }
            }

            // 结束任务
            $this->_delTask($article_id, $cron_id);
        }

        $this->_exit();
    }

    /**
     * 退出
     * @author zhonglei
     * @return void
     */
    private function _exit()
    {
        // 日志结束
        Log::record(sprintf('---%s %s CheckAttach END---', QY_DOMAIN, APP_IDENTIFIER), Log::INFO);
        exit('SUCCESS');
    }

    /**
     * 删除计划任务并退出
     * @author zhonglei
     * @param int $article_id 新闻ID
     * @param string $cron_id 计划任务ID
     * @return void
     */
    private function _delTask($article_id, $cron_id)
    {
        $taskServ = new TaskService();
        $taskServ->delete_by_conds([
            'article_id' => $article_id,
            'cron_id' => $cron_id,
        ]);

        $cronSdk = new Cron(Service::instance());
        $cronSdk->delete($cron_id);

        Log::record("delete task: {$cron_id}", Log::INFO);
        $this->_exit();
    }
}