CourseArticleService.class.php 9.85 KB
<?php
/**
 * Created by PhpStorm.
 * User: liyifei2012it
 * Date: 18/5/16
 * Time: 17:45
 */
namespace Common\Service;

use Com\PackageValidate;
use Common\Common\Msg;
use Common\Common\Teacher;
use Common\Common\Constant;
use Common\Model\CourseArticleModel;

class CourseArticleService extends AbstractService
{
    public function __construct()
    {
        parent::__construct();

        $this->_d = new CourseArticleModel();
    }

    /**
     * 校验线下课程参数
     * @ahthor liyifei
     * @param array $data 线下课程数据
     * @int int $ed_status 培训状态(1=草稿;2=已发布;3=已终止)
     * @int int $old_ed_status 原培训状态(1=草稿;2=已发布;3=已终止)
     * @return bool
     */
    public function check_data($data, $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED, $old_ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
    {
        if (empty($data)) {
            E('_ERR_COURSE_REQUEST_PARAM_LOSE');
        }

        // 验证规则
        $rules = [
            'article_id' => 'require|integer',
            'article_title' => 'require|max:64',
            'start_time' => 'require',
            'end_time' => 'require',
            'teacher_id' => 'require|integer|egt:0',
            'teacher_task_id' => 'integer|egt:0',
            'class_hour' => 'require|egt:0|elt:9999',
            'credit' => 'require|integer|egt:0|elt:9999',
            'address' => 'max:64',
            'cover_url' => 'max:500',
            'is_sign' => 'integer|in:1,2',
            'is_notice' => 'integer|in:1,2',
            'is_score' => 'integer|in:1,2',
        ];

        // 错误提示
        $message = [
            'article_id.require' => L('_EMPTY_ARTICLE_ID'),
            'article_title' => L('_EMPTY_ARTICLE_TITLE'),
            'start_time' =>  L('_EMPTY_ARTICLE_START_TIME'),
            'end_time' =>  L('_EMPTY_ARTICLE_END_TIME'),
            'teacher_id.require' => L('_EMPTY_ARTICLE_TEACHER_ID'),
            'class_hour.require' => L('_EMPTY_ARTICLE_CLASS_HOUR'),
            'credit.require' => L('_EMPTY_ARTICLE_CREDIT'),

            'article_id.integer' => L('_ERR_ARTICLE_ID'),
            'teacher_id.integer' => L('_ERR_ARTICLE_TEACHER_ID'),
            'teacher_task_id.integer' => L('_ERR_ARTICLE_TEACHER_TASK_ID'),
            'credit.integer' => L('_ERR_ARTICLE_CREDIT'),
            'address' => L('_ERR_ARTICLE_ADDRESS'),
            'cover_url' => L('_ERR_ARTICLE_COVER_URL'),
            'is_sign' => L('_ERR_ARTICLE_SIGN'),
            'is_notice' => L('_ERR_ARTICLE_NOTICE'),
            'is_score' => L('_ERR_ARTICLE_SCORE'),
        ];

        // 验证请求数据
        $validate = new PackageValidate();
        $validate->postData = $data;
        $validate->validateParams($rules, $message);

        // 授课任务
        if ($data['teacher_task_id'] > 0) {
            if (empty($data['teacher_id'])) {
                E('_ERR_COURSE_NOT_SET_TEACHER');
            }

            // 讲师与授课任务不匹配
            $teacherServ = &Teacher::instance();
            $task = $teacherServ->getTeackerTask($data['teacher_task_id']);
            if (empty($task) || $task['teacher_id'] != $data['teacher_id']) {
                E('_ERR_COURSE_TASK_NOT_MATCH');
            }
        }

        // 校验评分项
        $item_serv = new CourseItemService();
        if (isset($data['score_item'])) {
            $item_serv->check_data($data['score_item']);
        }

        // 修改已发布课程时,评分项数量、评分类型不可修改
        if ($data['article_id'] > 0 && $ed_status == Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED && $old_ed_status == Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED) {
            $diff_res = $item_serv->diff_item($data['article_id'], $data['score_item']);
            if (!$diff_res) {
                E('_ERR_SCORE_ITEM_NOT_UPDATE');
            }
        }

        return true;
    }

    /**
     * 保存线下课程(含新增和修改)
     * @ahthor liyifei
     * @param array $data 线下课程数据
     *      + Int article_id 课程ID(新建时为0)
     *		+ Int article_title 课程名称
     *		+ Int start_time 授课开始时间(毫秒)
     *		+ Int end_time 授课结束时间(毫秒)
     *		+ Int teacher_id 讲师ID
     *		+ Int teacher_task_id 讲师授课任务ID
     *		+ Int class_hour 讲师授课课时
     *		+ Int credit 学分
     *		+ Int address 授课地址
     *		+ Int cover_id 封面图片ID
     *		+ Int cover_url 封面图片URL
     *		+ Int content 课程介绍
     *		+ Int is_sign 是否启用签到(1=不启用;2=启用)
     *		+ Int is_notice 消息通知讲师(1=不开启;2=开启)
     *		+ Int is_score 是否启用评分(1=不启用;2=启用)
     *		+ Array score_item 评分设置(启用评分时,必填)
     *		+ Int score_item[].item_id:true:0 评分项ID(新增时,该值为0)
     *		+ String score_item[].content:true 评分内容
     *		+ Int score_item[].score_type:true 评分类型(1=课程内容;2=课程讲师)
     *		+ Int score_item[].score_order:true 排序
     * @int int $ed_status 培训状态(1=草稿;2=发布;3=已终止)
     * @int int $plan_use_status 先培训安排启用状态(0=禁用;1=启用)
     * @return int
     */
    public function save_course($data, $ed_status = Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED, $plan_use_status = Constant::PLAN_USE_STATUS_IS_FALSE)
    {
        $article_id = isset($data['article_id']) ? $data['article_id'] : 0;
        $score_item = isset($data['score_item']) ? $data['score_item'] : [];

        // 仅保留数据库字段
        $keys = ['article_title', 'start_time', 'end_time', 'teacher_id', 'teacher_task_id', 'class_hour', 'credit',
            'address', 'cover_id', 'cover_url', 'content', 'is_sign', 'is_notice', 'is_score'];
        $data = array_intersect_key_reserved($data, $keys, true);

        $cronServ = new CronService();
        $teacherServ = &Teacher::instance();

        // 新增课程
        if ($article_id == 0) {
            $article_id = $this->insert($data);
            $new_article = $this->get($article_id);

            // 需推送授课提醒的讲师
            $teacher_id = $new_article['teacher_id'];

        // 修改课程
        } else {
            // 原线下课程数据
            $old_article = $this->get($article_id);
            $this->update($article_id, $data);
            // 新线下课程数据
            $new_article = $this->get($article_id);

            // 讲师已变更
            if ($old_article['teacher_id'] != $new_article['teacher_id']) {
                $teacher_id = $new_article['teacher_id'];
            }

            // 删除计划任务(关闭签到 | 学分为0 | 培训安排被禁用)
            if (($old_article['is_sign'] == Constant::COURSE_IS_SIGN_IS_TRUE && $new_article['is_sign'] == Constant::COURSE_IS_SIGN_IS_FALSE && $ed_status == Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED)
                || ($old_article['credit'] > 0 && $new_article['credit'] == 0)
                || $plan_use_status == Constant::PLAN_USE_STATUS_IS_FALSE) {

                $cronServ->delCron('', $new_article['article_id']);
            }

            // 同步讲师数据至讲师中心(培训安排被禁用)
            if ($plan_use_status == Constant::PLAN_USE_STATUS_IS_FALSE) {
                $tmp_article = $new_article;
                // 将讲师ID设置为0
                $tmp_article['teacher_id'] = 0;
                $teacherServ->saveOfflineCourse($new_article);
            }
        }

        // 保存课程评分项
        $itemServ = new CourseItemService();
        $itemServ->save_item($article_id, $score_item);

        // 培训已发布状态、培训安排已启用
        if ($ed_status == Constant::EDUCATION_PUBLISH_STATUS_PUBLISHED && $plan_use_status == Constant::PLAN_USE_STATUS_IS_TRUE) {
            // 开启签到、有学分,保存计划任务
            if ($new_article['is_sign'] == Constant::COURSE_IS_SIGN_IS_TRUE && $new_article['credit'] > 0) {
                $cronServ->saveCron($new_article);
            }

            // 通知讲师中心,记录讲师授课任务、课时
            $teacherServ->saveOfflineCourse($new_article);

            // 给讲师推送课程提醒
            if ($new_article['is_notice'] == Constant::ARTICLE_IS_NOTICE_TRUE && !empty($teacher_id)) {
                $teacher = $teacherServ->getTeacher($teacher_id);
                if (!empty($teacher['uid'])) {
                    $this->sendNotice($teacher['uid'], $new_article);
                }
            }
        }

        return $article_id;
    }

    /**
     * 发送授课通知
     * @author liyifei
     * @param string $uid 用户ID
     * @param array $article 线下课程数据
     * @return void
     */
    public function sendNotice($uid, $article)
    {
        $url = oaUrl('Frontend/Index/Teacher/Index', [], '', 'Teacher');
        $start_time = rgmdate($article['start_time'], 'Y/m/d');
        $end_time = rgmdate($article['end_time'], 'Y/m/d');

        $desc = "课程名称:{$article['article_title']}\n";
        $desc .= "授课时间:{$start_time} - {$end_time}\n";
        if (strlen($article['address']) > 0) {
            $desc .= "授课地址:{$article['address']}";
        }

        $msg_data = [
            [
                'title' => '【授课通知】您被指派授课任务,点击查看',
                'description' => $desc,
                'url' => $url,
            ]
        ];

        $msgServ = &Msg::instance();
        $msgServ->sendNews($uid, null, null, $msg_data);
    }

    /**
     * 获取线下课程签到二维码图片Url
     * @author zhonglei
     * @param int $article_id 线下课程ID
     * @return string
     */
    public function getSignQrcodeUrl($article_id)
    {
        return oaUrl('Frontend/Index/SignQrcode/Index', ['article_id' => $article_id]);
    }
}