NoticeClient.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. <?php
  2. /**
  3. * QQ: 1123416584
  4. */
  5. namespace addons\notice\library;
  6. use addons\notice\library\server\Msg;
  7. use app\admin\model\notice\Notice;
  8. use app\admin\model\notice\NoticeEvent;
  9. use app\admin\model\notice\NoticeTemplate;
  10. use hnh\custom\Log;
  11. /**
  12. *
  13. * @package addons\notice\library
  14. */
  15. class NoticeClient
  16. {
  17. /**
  18. * @var object 对象实例
  19. */
  20. protected static $instance;
  21. // 所有的模版
  22. public $templateList = [];
  23. /**
  24. * 通知服务提供者
  25. * @var array
  26. */
  27. private $providers = [
  28. 'msg' => 'Msg',
  29. 'email' => 'Email',
  30. 'mptemplate' => 'Mptemplate'
  31. ];
  32. /**
  33. * 服务对象信息
  34. * @var array
  35. */
  36. protected $services = [];
  37. // 插件配置
  38. public $addonConfig = [];
  39. /**
  40. * 初始化
  41. * @access public
  42. * @param array $options 参数
  43. * @return NoticeClient
  44. */
  45. public static function instance($options = [])
  46. {
  47. if (is_null(self::$instance)) {
  48. self::$instance = new static($options);
  49. }
  50. return self::$instance;
  51. }
  52. public function __construct()
  53. {
  54. // 加载模板
  55. $this->templateList = NoticeTemplate::select();
  56. $this->registerProviders();
  57. $this->addonConfig = get_addon_config('notice');
  58. }
  59. /**
  60. * 发送消息通知
  61. *
  62. * @param $event
  63. * @param $params 参数必须和后台配置的完全一致
  64. *
  65. * @throws \think\exception\DbException
  66. */
  67. public function trigger($event, $params)
  68. {
  69. // 查询事件
  70. $event = NoticeEvent::get(['event' => $event]);
  71. if (!$event || $event['visible_switch'] == 0) {
  72. $this->error = '事件不存在';
  73. return false;
  74. }
  75. // 判断字段是否按规定传对了
  76. $needFields = json_decode($event['content'], true);
  77. $diff = array_diff_key($needFields, $params);
  78. if (count($diff) > 0) {
  79. // 记录日志
  80. $logData = [
  81. 'name' => $event['name'].'-缺少参数',
  82. 'event' => $event->toArray(),
  83. 'params' => $params,
  84. '缺少参数' => $diff
  85. ];
  86. Log::error($logData);
  87. // 发送失败次数
  88. $event->setInc('send_fail_num');
  89. $this->error = $event['name'].'-缺少参数';
  90. return false;
  91. }
  92. $platformArr = explode(',', $event['platform']);
  93. $typeArr = explode(',', $event['type']);
  94. $platformData = $this->getPlatformData();
  95. // 所有可发送消息的模板
  96. $templateList = array_filter($this->templateList,
  97. function ($item) use ($event, $platformArr, $typeArr, $platformData) {
  98. if ($item['notice_event_id'] != $event['id']) {
  99. return false;
  100. }
  101. if (!in_array($item['platform'], $platformArr)) {
  102. return false;
  103. }
  104. if (!in_array($item['type'], $typeArr)) {
  105. return false;
  106. }
  107. if (!isset($platformData[$item['platform']])) {
  108. return false;
  109. }
  110. if (!in_array($item['type'],$platformData[$item['platform']]['type'])) {
  111. return false;
  112. }
  113. if ($item['visible_switch'] == 0) {
  114. return false;
  115. }
  116. return true;
  117. }
  118. );
  119. foreach ($templateList as $item) {
  120. try{
  121. // 发送次数
  122. $event->setInc('send_num');
  123. $item->setInc('send_num');
  124. // 添加消息记录
  125. $noticeData = [
  126. 'name' => $event['name'],
  127. 'event' => $event['event'],
  128. 'platform' => $item['platform'],
  129. 'type' => $item['type'],
  130. 'to_id' => 0,
  131. 'content' => '',
  132. 'ext' => '',
  133. 'notice_template_id' => $item['id']
  134. ];
  135. $getNoticeData = $this->services[$item['type']]->getNoticeData($event, $item, $params);
  136. $noticeData = array_merge($noticeData, $getNoticeData);
  137. // 批量发送情况
  138. $to_id = is_array($noticeData['to_id']) ? $noticeData['to_id'] : [$noticeData['to_id']];
  139. foreach ($to_id as $v2) {
  140. $noticeData['to_id'] = $v2;
  141. Notice::create($noticeData);
  142. }
  143. }catch (\Exception $e) {
  144. // 记录日志
  145. $logData = [
  146. 'notice_template_id' => $item['id'],
  147. 'name' => $event['name'],
  148. 'event' => $event->toArray(),
  149. 'template' => $item->toArray(),
  150. 'params' => $params
  151. ];
  152. Log::catch('模板发送失败', $e, $logData);
  153. // 发送失败次数
  154. $this->error = $e->getMessage();
  155. $event->setInc('send_fail_num');
  156. $item->setInc('send_fail_num');
  157. }
  158. }
  159. return true;
  160. }
  161. // 获取配置
  162. public function getPlatformData()
  163. {
  164. $typeList = $this->getTypeList();
  165. $platformList = $this->getPlatformList();
  166. /*$list = [
  167. 'user' => [
  168. 'name' => '用户',
  169. 'type' => ['msg','email'],
  170. ],
  171. 'admin' => [
  172. 'name' => '后台',
  173. 'type' => ['msg','email'],
  174. ],
  175. ];*/
  176. $list = [];
  177. foreach ($platformList as $k=>$v) {
  178. $type = $this->addonConfig['open'][$k] ?? '';
  179. $type = explode(',', $type);
  180. $type = array_combine($type, $type);
  181. $type = array_intersect_key($type, $typeList);
  182. $listItem = [
  183. 'name' => $v,
  184. 'type' => $type,
  185. ];
  186. $list[$k] = $listItem;
  187. }
  188. return $list;
  189. }
  190. // 获取类型中文名称
  191. public function getTypeText($type)
  192. {
  193. return $this->getTypeList()[$type]?:'未知';
  194. }
  195. // 所有平台
  196. public function getPlatformList()
  197. {
  198. $all = ['user' => '用户', 'admin' => '后台'];
  199. $platform = $this->addonConfig['platform'];
  200. $platform = explode(',', $platform);
  201. $list = [];
  202. foreach ($all as $k => $v) {
  203. if (in_array($k, $platform)) {
  204. $list[$k] = $v;
  205. }
  206. }
  207. return $list;
  208. }
  209. // 所有类型
  210. public function getTypeList()
  211. {
  212. $all = (new NoticeEvent())->getTypeList();
  213. $platform = $this->addonConfig['type'];
  214. $platform = explode(',', $platform);
  215. $list = [];
  216. foreach ($all as $k => $v) {
  217. if (in_array($k, $platform)) {
  218. $list[$k] = $v;
  219. }
  220. }
  221. return $list;
  222. }
  223. // 根据平台和类型获取模板
  224. public function getTemplateByPlatformAndType($notice_event_id,$platform, $type)
  225. {
  226. $list = $this->templateList;
  227. foreach ($list as $item) {
  228. if ($item['platform'] == $platform && $item['type'] == $type && $item['notice_event_id'] == $notice_event_id) {
  229. return $item;
  230. }
  231. }
  232. return false;
  233. }
  234. /**
  235. * 错误信息
  236. * @var null
  237. */
  238. public $error = null;
  239. /**
  240. * 获取错误信息
  241. */
  242. public function getError()
  243. {
  244. return $this->error;
  245. }
  246. /**
  247. * 注册服务提供者
  248. */
  249. private function registerProviders()
  250. {
  251. foreach ($this->providers as $k => $v) {
  252. $objname = __NAMESPACE__ . "\\server\\{$v}";
  253. $this->services[$k] = new $objname();
  254. }
  255. }
  256. }