Notification.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. <?php
  2. namespace addons\shopro\notification;
  3. use think\queue\ShouldQueue;
  4. use addons\shopro\channel\Database;
  5. use addons\shopro\channel\Websocket;
  6. use addons\shopro\channel\Sms;
  7. use addons\shopro\channel\WechatMiniProgram;
  8. use addons\shopro\channel\WechatOfficialAccount;
  9. use addons\shopro\channel\WechatOfficialAccountBizsend;
  10. use addons\shopro\channel\Email;
  11. use app\admin\model\shopro\notification\Config;
  12. /**
  13. * 消息通知基类
  14. */
  15. class Notification implements ShouldQueue
  16. {
  17. // 队列名称,必须继承 ShouldQueue 接口
  18. protected $config = null;
  19. public function initConfig()
  20. {
  21. // 缓存 5 分钟
  22. $config = Config::where('event', $this->event)->select();
  23. $this->config = array_column($config, null, 'channel');
  24. }
  25. // 返回发送方式
  26. public function channels($notifiable)
  27. {
  28. $channels = [Database::class, Websocket::class];
  29. if (isset($this->config['Sms']) && $this->config['Sms']['status'] == 'enable') {
  30. $channels[] = Sms::class;
  31. }
  32. if (isset($this->config['Email']) && $this->config['Email']['status'] == 'enable') {
  33. $channels[] = Email::class;
  34. }
  35. if (isset($this->config['WechatOfficialAccount']) && $this->config['WechatOfficialAccount']['status'] == 'enable') {
  36. $channels[] = WechatOfficialAccount::class;
  37. }
  38. if (isset($this->config['WechatMiniProgram']) && $this->config['WechatMiniProgram']['status'] == 'enable') {
  39. $channels[] = WechatMiniProgram::class;
  40. }
  41. return $channels;
  42. }
  43. // 格式化模板数据
  44. public function formatParams($params, $type)
  45. {
  46. $paramsData = $params['data'] ?? [];
  47. $config = $this->config[$type] ?? [];
  48. if (!$config) {
  49. // 不能发送
  50. return $params;
  51. }
  52. $newData = [];
  53. if ($type == 'Email') {
  54. $newContent = $config['content'];
  55. if (preg_match_all("/(?<=(p:{)).+?(?=})/", $config['content'], $matches)) {
  56. foreach ($matches[0] as $k => $field) {
  57. $fieldVal = $paramsData[$field] ?? '';
  58. $newContent = str_replace("p:{" . $field . "}", $fieldVal, $newContent);
  59. }
  60. }
  61. $params['content'] = $newContent;
  62. } else {
  63. $content_arr = $config['content'];
  64. if (isset($content_arr['template_id']) && isset($content_arr['fields'])) {
  65. if (in_array($type, ['WechatOfficialAccountBizsend', 'WechatOfficialAccount', 'WechatMiniProgram', 'Sms'])) {
  66. $params['template_id'] = $content_arr['template_id'];
  67. }
  68. foreach ($content_arr['fields'] as $key => $data) {
  69. // 用户填写了才处理,没填的字段直接 pass
  70. if (isset($data['template_field']) && $data['template_field']) {
  71. if (isset($data['field'])) {
  72. $value = $paramsData[$data['field']] ?? '-';
  73. } else {
  74. $value = $data['value'];
  75. }
  76. $value = $value ?: '-';
  77. $value = $this->substrParams($data['template_field'], $value, $type);
  78. if (in_array($type, ['WechatMiniProgram', 'WechatOfficialAccountBizsend'])) {
  79. $newData[$data['template_field']] = ['value' => $value];
  80. } else {
  81. $newData[$data['template_field']] = $value;
  82. }
  83. }
  84. }
  85. }
  86. $params['data'] = $newData;
  87. }
  88. return $params;
  89. }
  90. // 字符串截取
  91. public function substrParams($key, $value, $type)
  92. {
  93. if ($type == 'sms') {
  94. $value = mb_substr($value, 0, 18);
  95. } else if (in_array($type, ['WechatMiniProgram', 'WechatOfficialAccount', 'WechatOfficialAccountBizsend'])) {
  96. $value = $this->substrMiniParams($key, $value);
  97. }
  98. return $value;
  99. }
  100. // 小程序裁剪参数
  101. private function substrMiniParams($key, $value)
  102. {
  103. switch(true) {
  104. case strpos($key, 'thing') !== false; // 事物
  105. $value = mb_substr($value, 0, 20);
  106. break;
  107. case strpos((string)$key, 'number') !== false; // 数字
  108. $value = mb_substr((string)$value, 0, 32);
  109. break;
  110. case strpos($key, 'letter') !== false; // 字母
  111. $value = mb_substr($value, 0, 32);
  112. break;
  113. case strpos($key, 'symbol') !== false; // 符号
  114. $value = mb_substr($value, 0, 5);
  115. break;
  116. case strpos($key, 'character_string') !== false;// 字符串
  117. $value = mb_substr($value, 0, 32);
  118. break;
  119. case strpos($key, 'phone_number') !== false; // 电话
  120. $value = mb_substr($value, 0, 17);
  121. break;
  122. case strpos($key, 'car_number') !== false; // 车牌
  123. $value = mb_substr($value, 0, 8);
  124. break;
  125. case strpos($key, 'name') !== false; // 姓名
  126. $value = mb_substr($value, 0, 10);
  127. break;
  128. case strpos($key, 'phrase') !== false; // 汉字
  129. $value = mb_substr($value, 0, 5);
  130. break;
  131. }
  132. return $value;
  133. }
  134. /**
  135. * 发送成功
  136. */
  137. public function sendOk($channel) {
  138. // 更新发送条数
  139. Config::where('event', $this->event)->where('channel', $channel)->setInc('send_num');
  140. }
  141. /**
  142. * 设置延迟时间
  143. */
  144. public function delay($second = 0) {
  145. if (!($this instanceof ShouldQueue)) {
  146. error_stop("该消息类型不支持队列,请先继承队列");
  147. }
  148. $this->delay = $second;
  149. return $this;
  150. }
  151. }