296 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
/**
 | 
						|
 *  QQ: 1123416584
 | 
						|
 */
 | 
						|
namespace addons\notice\library;
 | 
						|
 | 
						|
use addons\notice\library\server\Msg;
 | 
						|
use app\admin\model\notice\Notice;
 | 
						|
use app\admin\model\notice\NoticeEvent;
 | 
						|
use app\admin\model\notice\NoticeTemplate;
 | 
						|
use hnh\custom\Log;
 | 
						|
 | 
						|
/**
 | 
						|
 *
 | 
						|
 * @package addons\notice\library
 | 
						|
 */
 | 
						|
class NoticeClient
 | 
						|
{
 | 
						|
 | 
						|
    /**
 | 
						|
     * @var object 对象实例
 | 
						|
     */
 | 
						|
    protected static $instance;
 | 
						|
 | 
						|
    // 所有的模版
 | 
						|
    public $templateList = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * 通知服务提供者
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    private $providers = [
 | 
						|
        'msg'      => 'Msg',
 | 
						|
        'email'   => 'Email',
 | 
						|
        'mptemplate' => 'Mptemplate',
 | 
						|
        'miniapp' => 'Miniapp',
 | 
						|
        'sms' => 'Sms',
 | 
						|
    ];
 | 
						|
 | 
						|
    /**
 | 
						|
     * 服务对象信息
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected $services = [];
 | 
						|
 | 
						|
    // 插件配置
 | 
						|
    public $addonConfig = [];
 | 
						|
 | 
						|
    /**
 | 
						|
     * 初始化
 | 
						|
     * @access public
 | 
						|
     * @param array $options 参数
 | 
						|
     * @return NoticeClient
 | 
						|
     */
 | 
						|
    public static function instance($options = [])
 | 
						|
    {
 | 
						|
        if (is_null(self::$instance)) {
 | 
						|
            self::$instance = new static($options);
 | 
						|
        }
 | 
						|
 | 
						|
        return self::$instance;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    public function __construct()
 | 
						|
    {
 | 
						|
        // 加载模板
 | 
						|
        $this->templateList = NoticeTemplate::select();
 | 
						|
        $this->registerProviders();
 | 
						|
        $this->addonConfig = get_addon_config('notice');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 发送消息通知
 | 
						|
     *
 | 
						|
     * @param $event
 | 
						|
     * @param $params 参数必须和后台配置的完全一致
 | 
						|
     *
 | 
						|
     * @throws \think\exception\DbException
 | 
						|
     */
 | 
						|
    public function trigger($event, $params)
 | 
						|
    {
 | 
						|
        // 查询事件
 | 
						|
        $event = NoticeEvent::get(['event' => $event]);
 | 
						|
        if (!$event || $event['visible_switch'] == 0) {
 | 
						|
            $this->error = '事件不存在';
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
        // 判断字段是否按规定传对了
 | 
						|
        $needFields = json_decode($event['content'], true);
 | 
						|
        $diff = array_diff_key($needFields, $params);
 | 
						|
        if (count($diff) > 0) {
 | 
						|
            // 记录日志
 | 
						|
            $logData = [
 | 
						|
                'name' =>  $event['name'].'-缺少参数',
 | 
						|
                'event' => $event->toArray(),
 | 
						|
                'params' => $params,
 | 
						|
                '缺少参数' => $diff
 | 
						|
            ];
 | 
						|
            Log::error($logData);
 | 
						|
 | 
						|
            // 发送失败次数
 | 
						|
            $event->setInc('send_fail_num');
 | 
						|
            $this->error = $event['name'].'-缺少参数';
 | 
						|
            return false;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        $platformArr = explode(',', $event['platform']);
 | 
						|
        $typeArr = explode(',', $event['type']);
 | 
						|
        $platformData = $this->getPlatformData();
 | 
						|
 | 
						|
        // 所有可发送消息的模板
 | 
						|
        $templateList = array_filter($this->templateList,
 | 
						|
            function ($item) use ($event, $platformArr, $typeArr, $platformData) {
 | 
						|
                if ($item['notice_event_id'] != $event['id']) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                if (!in_array($item['platform'], $platformArr)) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                if (!in_array($item['type'], $typeArr)) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                if (!isset($platformData[$item['platform']])) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                if (!in_array($item['type'],$platformData[$item['platform']]['type'])) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                if ($item['visible_switch'] == 0) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        );
 | 
						|
 | 
						|
        foreach ($templateList as $item) {
 | 
						|
            try{
 | 
						|
                // 发送次数
 | 
						|
                $event->setInc('send_num');
 | 
						|
                $item->setInc('send_num');
 | 
						|
 | 
						|
                // 添加消息记录
 | 
						|
                $noticeData = [
 | 
						|
                    'name' => $event['name'],
 | 
						|
                    'event' => $event['event'],
 | 
						|
                    'platform' => $item['platform'],
 | 
						|
                    'type' => $item['type'],
 | 
						|
                    'to_id' => 0,
 | 
						|
                    'content' => '',
 | 
						|
                    'ext' => '',
 | 
						|
                    'notice_template_id' => $item['id']
 | 
						|
                ];
 | 
						|
                $getNoticeData = $this->services[$item['type']]->getNoticeData($event, $item, $params);
 | 
						|
                $noticeData = array_merge($noticeData, $getNoticeData);
 | 
						|
 | 
						|
                // 批量发送情况
 | 
						|
                $to_id = is_array($noticeData['to_id']) ? $noticeData['to_id'] : [$noticeData['to_id']];
 | 
						|
                foreach ($to_id as $v2) {
 | 
						|
                    $noticeData['to_id'] = $v2;
 | 
						|
                    Notice::create($noticeData);
 | 
						|
                }
 | 
						|
            }catch (\Exception $e) {
 | 
						|
                // 记录日志
 | 
						|
                $logData = [
 | 
						|
                    'notice_template_id' => $item['id'],
 | 
						|
                    'name' =>  $event['name'],
 | 
						|
                    'event' => $event->toArray(),
 | 
						|
                    'template' => $item->toArray(),
 | 
						|
                    'params' => $params
 | 
						|
                ];
 | 
						|
                Log::catch('模板发送失败', $e, $logData);
 | 
						|
 | 
						|
                // 发送失败次数
 | 
						|
                $this->error = $e->getMessage();
 | 
						|
                $event->setInc('send_fail_num');
 | 
						|
                $item->setInc('send_fail_num');
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    // 获取配置
 | 
						|
    public function getPlatformData()
 | 
						|
    {
 | 
						|
        $typeList = $this->getTypeList();
 | 
						|
        $platformList = $this->getPlatformList();
 | 
						|
 | 
						|
        /*$list = [
 | 
						|
            'user' => [
 | 
						|
                'name' => '用户',
 | 
						|
                'type' => ['msg','email'],
 | 
						|
            ],
 | 
						|
            'admin' => [
 | 
						|
                'name' => '后台',
 | 
						|
                'type' => ['msg','email'],
 | 
						|
            ],
 | 
						|
        ];*/
 | 
						|
 | 
						|
        $list = [];
 | 
						|
        foreach ($platformList as $k=>$v) {
 | 
						|
            $type = $this->addonConfig['open'][$k] ?? '';
 | 
						|
            $type =  explode(',', $type);
 | 
						|
            $type = array_combine($type, $type);
 | 
						|
            $type = array_intersect_key($type, $typeList);
 | 
						|
            $listItem = [
 | 
						|
                'name' => $v,
 | 
						|
                'type' => $type,
 | 
						|
            ];
 | 
						|
            $list[$k] = $listItem;
 | 
						|
        }
 | 
						|
 | 
						|
        return $list;
 | 
						|
    }
 | 
						|
 | 
						|
    // 获取类型中文名称
 | 
						|
    public function getTypeText($type)
 | 
						|
    {
 | 
						|
        return $this->getTypeList()[$type]?:'未知';
 | 
						|
    }
 | 
						|
 | 
						|
    // 所有平台
 | 
						|
    public function getPlatformList()
 | 
						|
    {
 | 
						|
        $all =  ['user' => '用户', 'admin' => '后台'];
 | 
						|
        $platform = $this->addonConfig['platform'];
 | 
						|
        $platform = explode(',', $platform);
 | 
						|
 | 
						|
        $list = [];
 | 
						|
        foreach ($all as $k => $v) {
 | 
						|
            if (in_array($k, $platform)) {
 | 
						|
                $list[$k] = $v;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $list;
 | 
						|
    }
 | 
						|
 | 
						|
    // 所有类型
 | 
						|
    public function getTypeList()
 | 
						|
    {
 | 
						|
        $all =  (new NoticeEvent())->getTypeList();
 | 
						|
        $platform = $this->addonConfig['type'];
 | 
						|
        $platform = explode(',', $platform);
 | 
						|
 | 
						|
        $list = [];
 | 
						|
        foreach ($all as $k => $v) {
 | 
						|
            if (in_array($k, $platform)) {
 | 
						|
                $list[$k] = $v;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return $list;
 | 
						|
    }
 | 
						|
 | 
						|
    // 根据平台和类型获取模板
 | 
						|
    public function getTemplateByPlatformAndType($notice_event_id,$platform, $type)
 | 
						|
    {
 | 
						|
        $list = $this->templateList;
 | 
						|
        foreach ($list as $item) {
 | 
						|
            if ($item['platform'] == $platform && $item['type'] == $type && $item['notice_event_id'] == $notice_event_id) {
 | 
						|
                return $item;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 错误信息
 | 
						|
     * @var null
 | 
						|
     */
 | 
						|
    public $error = null;
 | 
						|
 | 
						|
    /**
 | 
						|
     * 获取错误信息
 | 
						|
     */
 | 
						|
    public function getError()
 | 
						|
    {
 | 
						|
        return $this->error;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * 注册服务提供者
 | 
						|
     */
 | 
						|
    private function registerProviders()
 | 
						|
    {
 | 
						|
        foreach ($this->providers as $k => $v) {
 | 
						|
            $objname = __NAMESPACE__ . "\\server\\{$v}";
 | 
						|
            $this->services[$k] = new $objname();
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |