AbstractService.class.php 11.5 KB
<?php
/**
 * AbstractService.class.php
 * Service 层基类
 * @author: zhuxun37
 * @version: $Id$
 * @copyright: vchangyi.com
 */

namespace Common\Service;

use Common\Common\Attach;
use Common\Common\Constant;
use Common\Common\Msg;
use Common\Common\Tag;
use VcySDK\Member;
use VcySDK\Service;
use VcySDK\Exception;
use Common\Service\TagService;

abstract class AbstractService extends \Com\Service
{
    // 成功发布直播
    const MSG_LIVE_PUBLISH = 1;

    // 直播被编辑
    const MSG_LIVE_UPDATE = 2;

    // 未参与提醒消息
    const MSG_REMAIND_NO_JOIN_USERS = 3;

    // 直播前X分钟推送消息
    const MSG_LIVE_WILL_START = 4;

    // 直播开始
    const MSG_LIVE_START = 5;

    // 针对讲师的信息
    const MSG_LECTURER_APPOINTMENT = 6;

    // 直播默认封面
    const DEFAULT_LIVE_COVER = 'http://st.vchangyi.com/yuanquan/live/banner.jpg';

    // 构造方法
    public function __construct()
    {

        parent::__construct();
    }

    /**
     * 格式化直播封面图片地址
     * @param string $cover_id  封面 ID
     * @param bool $is_show     是否显示默认图
     * @return string           封面 URL
     */
    public function formatCover($cover_id, $is_show = true)
    {
        // 初始化图片地址
        $cover_url = '';

        if (!empty($cover_id)) {
            $cover_url = imgUrlReal($cover_id);
        } elseif ($is_show) {
            // 需要显示图片
            $cover_url =  self::DEFAULT_LIVE_COVER;
        }

        return $cover_url;
    }

    /**
     * 即时消息通知方法 【发消息统一写这里,方便维护】
     * @param $params -通知参数
     *          + uids      -用户uid数组
     *              + memID     -用户uid
     *          + dp_ids    -部门id数组
     *              + dpID      -部门id
     *          + tag_ids   -标签id数组
     *              + tagID     -标签id
     *          + job_ids   -岗位id数组
     *              + jobID     -岗位id
     *          + role_ids  -角色id数组
     *              + roleID    -角色id
     *          + lm_id     -直播ID
     *          + name      -直播标题
     *          + start_time    -直播开始时间
     *          + estimated_duration    -直播预计时长
     *          + desc      -直播摘要
     * @param $type -通知文案类型
     * @return bool
     */
    public function sendMsg($params, $type)
    {
        // 获取应用名称
        $application_name = cfg('APPLICATION_NAME');

        // 过滤内容中的空格标签
        $search = ["&nbsp;","&nbsp"];
        $replace = [" ", " "];
        $content = str_replace($search, $replace, strip_tags($params['desc']));

        // 开始时间
        $rgmDate = rgmdate($params['start_time'], 'Y-m-d H:i');

        // 本方法根据类型区分拼接不通的文案
        switch ($type) {

            case self::MSG_LIVE_PUBLISH:
                $data = [
                    'title' => '【' . cfg('APPLICATION_NAME') . '】有新的直播活动发布,快来观看吧!',
                    'description' => "标题:{$params['name']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['estimated_duration']}分钟\r\n直播简介:" . $this->cutstr($content, 0, 20),
                    'picUrl' => '',
                ];
                break;
            case self::MSG_REMAIND_NO_JOIN_USERS:

                $data = [
                    'title' => '【' . $application_name . '】您有一个直播未观看,快去瞧瞧吧!',
                    'description' => "标题:{$params['name']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['estimated_duration']}分钟\r\n直播简介:" . $this->cutstr($content, 0, 20),
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LIVE_WILL_START:
                $data = [
                    'title' => '【' . $application_name . '】直播活动仅剩' . $params['notice_will_start'] . '分钟开始,快来观看吧!',
                    'description' => "标题:{$params['name']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['estimated_duration']}分钟\r\n直播简介:" . $this->cutstr($content, 0, 20),
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LIVE_START:
                $data = [
                    'title' => '【' . $application_name . '】直播活动已经开始,快来观看吧!',
                    'description' => "标题:{$params['name']}\r\n开始时间:{$rgmDate}\r\n预计时长:{$params['estimated_duration']}分钟\r\n直播简介:" . $this->cutstr($content, 0, 20),
                    'picUrl' => '',
                ];
                break;
            case self::MSG_LECTURER_APPOINTMENT:
                // 直播地址
                $pushUrl = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] .
                    '/admincp/#/live-pc?lm_id=' . $params['lm_id'];
                // 跳转地址 (send 方法内用到)
                $params['jumpUrl'] = oaUrl('Frontend/Index/InstructorGuide/Index', ['lm_id' => $params['lm_id']]);

                $data = [
                    'title' => '【' . $application_name . '】您已被设置为直播讲师,请做好准备!',
                    'description' => "标题:{$params['name']}\r\n开始时间:{$rgmDate}\r\n直播口令:{$params['lecturer_pwd']}\r\n直播地址:" . $pushUrl,
                    'picUrl' => '',
                ];
                break;
            default:

                return true;
        }

        $this->send($params, $data);

        return true;
    }

    /**
     * 发送消息
     * @param $params -通知参数
     *          + is_all    -全公司
     *          + uids      -用户uid数组
     *              + memID     -用户uid
     *          + dp_ids    -部门id数组
     *              + dpID      -部门id
     *          + tag_ids   -标签id数组
     *              + tagID     -标签id
     *          + job_ids   -岗位id数组
     *              + jobID     -岗位id
     *          + role_ids  -角色id数组
     *              + roleID    -角色id
     *          + lm_id   -直播ID
     * @param array $condition 消息参数
     *          + title  -标题
     *          + description -内容
     *          + picUrl -图片URL
     * @return bool
     */
    private function send($params = [], $condition = [])
    {
        // 发送消息接收人
        $msgUser = !empty($params['uids']) ? $params['uids'] : [];
        $toUser = isset($params['is_all']) && !empty($params['is_all']) ? '@all' : $msgUser;

        // 发送消息部门
        $toParty = !empty($params['dp_ids']) ? $params['dp_ids'] : [];

        // 角色或者岗位发送消息
        if (!empty($params['job_ids']) || !empty($params['role_ids'] || !empty($params['tag_ids']))) {

            // 获取角色和岗位下的人员
            $uids = $this->get_job_role_uids($params);

            // 如果权限里有人员并且选择的不是全公司
            if (!empty($uids) && empty($params['is_all'])) {

                $toUser = array_merge($toUser, $uids);

                // 去重复人员
                $toUser = array_unique($toUser);
            }
        }

        // 如果用户和部门为空则不发消息
        if (empty($toUser) && empty($toParty)) {

            return true;
        }

        $articles = array(
            array(
                'title' => $condition['title'],
                'description' => $condition['description'],
                'url' =>
                    !isset($params['jumpUrl']) ?
                        oaUrl('Frontend/Index/LiveRoom/Index', array('lm_id' => $params['lm_id'])) :
                        $params['jumpUrl'],
                'picUrl' => '',
            ),
        );

        try {
            $msgServ = &Msg::instance();
            $msgServ->sendNews($toUser, $toParty, '', $articles);

        } catch (\Exception $e) {

            \Think\Log::record('发送消息失败:::' . var_export($e, true));
            E($e->getCode() . ':' . $e->getMessage());
        }

        return true;
    }

    /**
     * 根据用户岗位角色标签获取用户uids
     * @param array $params
     *               + job_ids 岗位数据
     *               + role_ids 角色数据
     * @return array
     */
    public function get_job_role_uids($params = [])
    {
        $uids = [];

        // 处理岗位
        if (!empty($params['job_ids'])) {

            $params['job_ids'] = array_unique($params['job_ids']);
            sort($params['job_ids']);
            // 初始化SDK
            $member = new Member(Service::instance());

            // 获取岗位列表
            $job_list = $member->listAll(array('jobIdList' => $params['job_ids']));
            $job_list = $member->listAll(array('jobIdList' => $params['job_ids']), 1, $job_list['total']);

            // 如果岗位下存在人员
            if (!empty($job_list['list'])) {
                $uids = array_column($job_list['list'], 'memUid');
            }

        }

        // 处理角色
        if (!empty($params['role_ids'])) {

            $params['role_ids'] = array_unique($params['role_ids']);

            sort($params['role_ids']);

            // 初始化SDK
            $member = new Member(Service::instance());

            // 获取角色列表
            $role_List = $member->listAll(array('roleIdList' => $params['role_ids']));
            $role_List = $member->listAll(array('roleIdList' => $params['role_ids']), 1, $role_List['total']);

            // 如果岗位下存在人员
            if (!empty($role_List['list'])) {

                $uids = array_merge($uids, array_column($role_List['list'], 'memUid'));
            }

        }

        // 处理标签
        if (!empty($params['tag_ids'])) {

            $params['tag_ids'] = array_unique($params['tag_ids']);

            sort($params['tag_ids']);

            $tag = new Tag();
            $tag_List = $tag->listUserByTagId($params['tag_ids'], 1, 1000);

            // 如果标签下存在人员
            if (!empty($tag_List['list'])) {

                $uids = array_merge($uids, array_column($tag_List['list'], 'memUid'));
            }

        }

        return $uids;
    }

    /**
     * 字符串截取,支持中文和其他编码
     * @param string $str 需要转换的字符串
     * @param int $start 开始位置
     * @param int $length 截取长度
     * @param string $charset 编码格式
     * @param bool $suffix 截断显示字符
     * @return string
     */
    public function cutstr($str, $start = 0, $length = 0, $charset = "utf-8", $suffix = true)
    {
        if (function_exists("mb_substr")) {
            $slice = mb_substr($str, $start, $length, $charset);
        } elseif (function_exists('iconv_substr')) {
            $slice = iconv_substr($str, $start, $length, $charset);
            if (false === $slice) {
                $slice = '';
            }
        } else {
            $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
            $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
            $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
            $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
            preg_match_all($re[$charset], $str, $match);
            $slice = join("", array_slice($match[0], $start, $length));
        }

        if (get_str_len($str) > $length && $slice) {

            $slice = $slice . '...';
        }

        return $suffix ? $slice : $slice;
    }

}