<?php
/**
 * Service 层基类
 * AbstractService.class.php
 * @copyright: vchangyi.com
 */

namespace Common\Service;

use Common\Common\Cache;
use Common\Common\Department;
use Common\Common\User;
use Common\Common\Msg;
use Common\Model\CommonModel;
use Common\Model\EducationModel;
use Common\Model\RightModel;

abstract class AbstractService extends \Com\Service
{
    // 每页数量
    const PAGE_LIMIT_DEFAULT = 10;

    // 默认页码
    const PAGE_DEFAULT = 1;

    // 考试默认图片
    const DEFAULT_TRAIN_COVER = '/admincp/imgs/client/app/components/my-app/train-new/train-add/train-default-pic.jpg';

    // 全公司
    const IS_ALL = 1;
    // 非全公司
    const NOT_IS_ALL = 0;

    // 查询人员状态:已关注
    const USER_STATUS_FOLLOW = 1;

    // 发消息类型:培训通知
    const MSG_EDUCATION_PUBLISH = 1;
    // 发消息类型:培训提醒
    const MSG_EDUCATION_REMIND = 2;
    // 发消息类型:培训报名通知
    const MSG_EDUCATION_SIGN = 3;
    // 发消息提醒:审核通知
    const MSG_CHECK_STATUS = 4;
    // 发消息提醒:发放勋章
    const MSG_GIVE_MEDAL = 5;

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

        parent::__construct();
    }

    /**
     * 即时消息通知方法 【发消息统一写这里,方便维护】
     *
     * @param $params -通知参数
     *          + uids      -用户uid数组
     *              + memID     -用户uid
     *          + dp_ids    -部门id数组
     *              + dpID      -部门id
     *          + tag_ids   -标签id数组
     *              + tagID     -标签id
     *          + ed_id   -培训ID
     *          + description -摘要
     *          + img_id -封面图片ID
     *          + name -培训名称
     *          + address -培训地址
     *          + msg -提前终止原因
     *          + content -提醒内容
     *          + begin_time -开始时间
     *          + end_time -结束时间
     *          + check_status -审核状态
     * @param $type -通知文案类型
     *
     * @return bool
     */
    public function send_msg($params, $type)
    {
        // 获取运营管理icon对应的应用名称
        $recommender_m = new CommonModel('CommonRecommender', 'oa_');
        $icon_conditons = [
            'app_dir' => 'Train',
            'type' => 2
        ];
        $recommender = $recommender_m->get_by_conds($icon_conditons);
        $appName = $recommender['title'];

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

                $data = [
                    'title' => '【' . $appName . '】' . $params['name'],
                    'description' => rgmdate((string)$params['begin_time'],
                            'Y-m-d H:i') . '-' . rgmdate((string)$params['end_time'],
                            'Y-m-d H:i') . "\r\n" . $params['address'],
                    'picUrl' => $this->format_cover($params['img_id']),
                ];
                break;

            case self::MSG_EDUCATION_REMIND:

                $data = [
                    'title' => '【' . $appName . '】消息提醒',
                    'description' => '培训名称:' . $this->cutstr($params['name'], 0,
                            20) . "\r\n通知内容:" . $this->cutstr($params['content'], 0,
                            80) . "\r\n通知时间:" . rgmdate(strval(MILLI_TIME), 'Y-m-d'),
                ];
                break;

            case self::MSG_CHECK_STATUS:

                $data = [
                    'title' => '【' . $appName . '】报名审核',
                    'description' => '培训名称:' . $this->cutstr($params['name'], 0,
                            20) . "\r\n审核状态:" . $params['check_status'] . "\r\n通知内容:" . $this->cutstr($params['content'],
                            0, 80) . "\r\n审核时间:" . rgmdate(strval(MILLI_TIME),
                            'Y-m-d'),
                ];
                break;

            case self::MSG_EDUCATION_SIGN:
                $data = [
                    'title' => '【' . $appName . '】报名支付',
                    'description' => '培训名称:' . $this->cutstr($params['name'], 0,
                            20) . "\r\n支付状态:" . $params['pay_status'] . "\r\n支付时间:" . rgmdate((string)$params['pay_time'],
                            'Y-m-d H:i'),
                ];
                break;

            case self::MSG_GIVE_MEDAL:

                $app_name = cfg('APPLICATION_NAME', null, '');

                $data = [
                    'title' => '【' . $appName . '】培训激励',
                    'description' => '消息名称:恭喜您,获得【' . $params['name'] . '】勋章' . "\r\n获取渠道:{$app_name}-"
                        . $params['ed_name'] . "\r\n获取时间:" . rgmdate(strval(MILLI_TIME), 'Y-m-d H:i'),
                ];
                break;

            default:

                return true;
        }

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

        return true;
    }

    /**
     * 发送消息
     *
     * @param $params -通知参数
     *          + uids      -用户uid数组
     *              + memID     -用户uid
     *          + dp_ids    -部门id数组
     *              + dpID      -部门id
     *          + tag_ids   -标签id数组
     *              + tagID     -标签id
     *          + ed_id   -培训ID
     *          + my_medal   -勋章消息标识
     * @param array $condition 消息参数
     *          + title  -标题
     *          + description -内容
     *          + picUrl -图片URL
     *
     * @return bool
     */
    private function send($params = [], $condition = [])
    {
        // 发送消息接收人
        $toUser = array_unique(array_filter(array_column($params['uids'], 'memID')));
        if (empty($toUser)) {

            $toUser = $params['uids'];
        }

        $msgUser = implode('|', $toUser);

        // 发送消息部门
        $toParty = array_unique(array_filter(array_column($params['dp_ids'], 'dpID')));
        if (empty($toParty)) {

            $toParty = $params['dp_ids'];
        }
        // 发送消息标签
        $toTag = array_unique(array_filter(array_column($params['tag_ids'], 'tagID')));
        if (empty($toTag)) {

            $toTag = $params['tag_ids'];
        }

        // 非勋章消息
        $my_medal = 0;
        // 勋章消息
        if ($params['my_medal']) {

            $my_medal = $params['my_medal'];
        }

        // 实例化发消息SDK
        $sdk_msg = Msg::instance();
        $msg['toUser'] = !empty($msgUser) ? $msgUser : ''; // 接收人
        $msg['toParty'] = !empty($toParty) ? implode('|', $toParty) : '';
        $msg['toTag'] = !empty($toTag) ? implode('|', $toTag) : '';
        $msg['articles'] = [
            [
                'title' => $condition['title'],
                'description' => $condition['description'],
                'url' => oaUrl('Frontend/Index/Msg/Index',
                    [
                        'ed_id' => $params['ed_id'],
                        'my_medal' => $my_medal
                    ]
                ),
                'picUrl' => $condition['picUrl'],
            ],
        ];

        $sdk_msg->sendNews($msg['toUser'], $msg['toParty'], $msg['toTag'], $msg['articles']);

        return true;
    }

    /**
     * 获取用户信息列表
     *
     * @param array
     *
     * @return array
     */
    public function get_all_user_by_cache($uids = [])
    {
        // 用户信息初始化
        $user = &User::instance();
        $cache = &Cache::instance();

        $user_list = [];

        // 防止缓存不存在时出错
        try {
            $user_list = $cache->get('Common.Train_User_List');
        } catch (\Think\Exception $e) {
            \Think\Log::record($e);

        } catch (\Exception $e) {
            \Think\Log::record($e);
        }

        $user_res = $user->listBasicByConds(['memSubscribeStatus' => self::USER_STATUS_FOLLOW], 1, 1);

        // 如果缓存不存在
        if (empty($user_list) || (count($user_list) != $user_res['total'])) {

            $users = $user->listAll();
            $user_list = [];
            foreach ($users as $v) {

                if ($v['memSubscribeStatus'] != self::USER_STATUS_FOLLOW) {
                    // 过滤未关注的用户
                    continue;
                }

                $arr = [
                    'memUid' => $v['memUid'],
                    'memUserid' => $v['memUserid'],
                    'memMobile' => $v['memMobile'],
                    'memEmail' => $v['memEmail'],
                    'memActive' => $v['memActive'],
                    'memUsername' => $v['memUsername'],
                    'memFace' => $v['memFace'],
                    'memSubscribeStatus' => $v['memSubscribeStatus'],
                    'memJob' => $v['memJob'],
                    'memRole' => $v['memRole'],
                    'dpName' => $v['dpName']
                ];

                $user_list[$v['memUid']] = $arr;
            }

            if (!empty($user_list)) {
                // 实例化缓存
                $cache->set('Common.Train_User_List', $user_list);
            }
        }

        if (empty($uids)) {

            return $user_list;
        }

        $user_info_list = [];
        foreach ($user_list as $k => $v) {
            if (in_array($k, $uids)) {

                $user_info_list[$k] = $v;
            }
        }

        // 获取缓存中不存在的用户信息
        $all_uids = array_filter(array_column($user_list, 'memUid'));
        $no_uids = array_diff($uids, $all_uids);

        // 获取缓存中不存在的或者已被删除的用户信息
        foreach ($no_uids as $_v) {
            $users_info = $user->getByUid($_v);

            $arr = [];

            $arr['memUid'] = $users_info['memUid'];
            $arr['memUserid'] = $users_info['memUserid'];
            $arr['memMobile'] = $users_info['memMobile'];
            $arr['memEmail'] = $users_info['memEmail'];
            $arr['memActive'] = $users_info['memActive'];
            $arr['memUsername'] = $users_info['memUsername'];
            $arr['memFace'] = $users_info['memFace'];
            $arr['memSubscribeStatus'] = $users_info['memSubscribeStatus'];
            $arr['memJob'] = $users_info['memJob'];
            $arr['memRole'] = $users_info['memRole'];
            $arr['dpName'] = $users_info['dpName'];

            $user_info_list[$arr['memUid']] = $arr;
        }

        return $user_info_list;
    }


    /**
     * 根据部门ID集合,角色ID,岗位ID获取人员ID集合
     *
     * @author daijun
     *
     * @param array $dp_ids 部门ID集合
     * @param String $role_id 角色ID
     * @param String $job_id 岗位ID
     * @param String $memUsername 用户名
     *
     * @return array
     */
    public function list_uids_by_dp_job_role($dp_ids = [], $role_id = '', $job_id = '', $memUsername = '')
    {
        $User = new User();
        // 部门查询
        $uids = [];
        if ($dp_ids) {
            $department = new Department();
            $dpIDs = array_unique($dp_ids);
            sort($dpIDs);
            // 查询子部门
            $department_data = $department->list_childrens_by_cdid($dpIDs, true);
            // 搜索当前部门
            $department_data = array_merge($dpIDs, $department_data);
            $department_data = array_unique($department_data);

            // 升序
            sort($department_data);
            // 查询部门所有用户
            $user_list = $User->listAll(
                [
                    'dpIdList' => $department_data,
                    'memSubscribeStatus' => self::USER_STATUS_FOLLOW
                ]);
            $dpid_uid = array_column($user_list, 'memUid');
            $uids = $dpid_uid;
        }

        // 角色查询
        if ($role_id) {
            $role_ids = [$role_id];
            $user_list = $User->listAll(
                [
                    'roleIdList' => $role_ids,
                    'memSubscribeStatus' => self::USER_STATUS_FOLLOW
                ]);
            $role_uid = array_column($user_list, 'memUid');

            if ($dp_ids) {
                $uids = array_intersect($uids, $role_uid);
            } else {
                $uids = $role_uid;
            }
        }

        // 岗位查询
        if ($job_id) {
            $job_ids = [$job_id];
            $user_list = $User->listAll(
                [
                    'jobIdList' => $job_ids,
                    'memSubscribeStatus' => self::USER_STATUS_FOLLOW
                ]);
            $job_uid = array_column($user_list, 'memUid');

            if ($dp_ids || $role_id) {
                $uids = array_intersect($uids, $job_uid);
            } else {
                $uids = $job_uid;
            }
        }

        // 按照名称搜索
        if ($memUsername) {
            $user_list = $User->listAll(
                [
                    'memUsername' => $memUsername,
                    'memSubscribeStatus' => self::USER_STATUS_FOLLOW
                ]);
            $user_uid = array_column($user_list, 'memUid');
            if (!empty($uids)) {
                $uids = array_intersect($uids, $user_uid);
            } else {
                $uids = $user_uid;
            }
        }

        return $uids;
    }

    /**
     * 字符串截取,支持中文和其他编码
     *
     * access public
     *
     * @param string $str 需要转换的字符串
     * @param int $start 开始位置
     * @param int $length 截取长度
     * @param string $charset 编码格式
     * @param bool $suffix 截断显示字符
     *
     * @return string
     */
    public function cutstr($str, $start, $length, $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 $slice;
    }

    /**
     * 格式化培训的封面图片地址
     *
     * @param string $cover_id 封面 ID
     *
     * @return string        封面 URL
     */
    public function format_cover($cover_id)
    {
        // 初始化默认图片地址
        $cover_url = cfg('PROTOCAL') . $_SERVER['HTTP_HOST'] . self::DEFAULT_TRAIN_COVER . '?time=' . time();

        if (!empty($cover_id)) {

            $cover_url = imgUrlReal($cover_id);
        }

        return $cover_url;
    }

    /**
     * 替换字符串中的/r/n为回车
     *
     * @param string $str 字符串
     *
     * @return string
     */
    public function Enter($str = '')
    {

        $str = trim($str); //清除字符串两边的空格

        $replace = ["\r\n", "\n", "\r", "&crarr;", "&#8629;"];

        return trim(str_replace($replace, "<br/>", $str)); //返回字符串

    }


    /**
     * 更新首页推荐
     *
     * @param string $ed_id 培训ID
     */
    public function recommender($ed_id = '')
    {

        $edu_serv = new EducationModel();

        // 获取培训数据
        $education = $edu_serv->get($ed_id);

        // 开启首页推荐
        if (EducationService::RECOMMEND_INDEX_TRUE == $education['ed_is_recommend']) {

            $url = rpcUrl('/Public/Rpc/Recommender/ArticleUpdate');

            $rpc_params = [
                'app' => 'train',
                'dataCategoryId' => '',
                'dataId' => $ed_id,
                'title' => $education['ed_name'],
                'summary' => $education['ed_introductions'],
                'attachId' => $education['ed_cover_id'],
                'pic' => !empty($education['ed_cover_id']) ? imgUrlReal($education['ed_cover_id']) : '',
                'url' => 'Train/Frontend/Index/Msg?&ed_id=' . $ed_id,
            ];

            $right_serv = new RightModel();

            // 获取权限表数据
            $right_all = $right_serv->get_by_conds([
                'obj_type' => 1, // 权限类型为全公司
                'ed_id' => $ed_id
            ]);

            // 是否推荐给全公司
            if (empty($right_all)) {

                $right_user_list = $this->_d->list_by_conds(['ed_id' => $ed_id]);

                $uids = array_unique(array_filter(array_column($right_user_list, 'ru_uid')));

                if (!empty($uids)) {
                    sort($uids);
                    // 获取权限数据
                    $rpc_params['right']['users'] = $uids;

                    \Com\Rpc::phprpc($url)->invoke('Index', $rpc_params);
                }

            } else {
                $rpc_params['right'] = [];
                \Com\Rpc::phprpc($url)->invoke('Index', $rpc_params);
            }

        }
    }
}