WechatMessageService.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LikeShop100%开源免费商用电商系统
  4. // +----------------------------------------------------------------------
  5. // | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
  6. // | 开源版本可自由商用,可去除界面版权logo
  7. // | 商业版本务必购买商业授权,以免引起法律纠纷
  8. // | 禁止对系统程序代码以任何目的,任何形式的再发布
  9. // | Gitee下载:https://gitee.com/likeshop_gitee/likeshop
  10. // | 访问官网:https://www.likemarket.net
  11. // | 访问社区:https://home.likemarket.net
  12. // | 访问手册:http://doc.likemarket.net
  13. // | 微信公众号:好象科技
  14. // | 好象科技开发团队 版权所有 拥有最终解释权
  15. // +----------------------------------------------------------------------
  16. // | Author: LikeShopTeam
  17. // +----------------------------------------------------------------------
  18. namespace app\common\service;
  19. use app\common\enum\NoticeEnum;
  20. use app\common\enum\UserTerminalEnum;
  21. use app\common\logic\NoticeLogic;
  22. use app\common\model\Notice;
  23. use app\common\model\NoticeSetting;
  24. use app\common\model\UserAuth;
  25. use EasyWeChat\Factory;
  26. use think\facade\Log;
  27. /**
  28. * 微信消息服务层
  29. * Class WechatMessageService
  30. * @package app\common\service
  31. */
  32. class WechatMessageService
  33. {
  34. /** Easychat实例
  35. * @var null
  36. */
  37. protected $app = null;
  38. protected $config = null;
  39. protected $openid = null;
  40. protected $templateId = null;
  41. protected $notice = null;
  42. protected $platform = null;
  43. /**
  44. * @notes 架构方法
  45. * @param $userId
  46. * @param $platform
  47. * @author Tab
  48. * @date 2021/8/20 14:21
  49. */
  50. public function __construct($userId, $platform)
  51. {
  52. $this->platform = $platform;
  53. if($platform == NoticeEnum::OA) {
  54. $terminal = UserTerminalEnum::WECHAT_OA;
  55. $this->config = [
  56. 'app_id' => ConfigService::get('official_account','app_id'),
  57. 'secret' => ConfigService::get('official_account','app_secret')
  58. ];
  59. $this->app = Factory::officialAccount($this->config);
  60. }
  61. if($platform == NoticeEnum::MNP) {
  62. $terminal = UserTerminalEnum::WECHAT_MMP;
  63. $this->config = [
  64. 'app_id' => ConfigService::get('mini_program','app_id'),
  65. 'secret' => ConfigService::get('mini_program','app_secret')
  66. ];
  67. $this->app = Factory::miniProgram($this->config);
  68. }
  69. $userAuth = UserAuth::where([
  70. 'user_id' => $userId,
  71. 'terminal' => $terminal ?? -999
  72. ])->findOrEmpty()->toArray();
  73. $this->openid = $userAuth['openid'] ?? '';
  74. }
  75. /**
  76. * @notes 发送消息
  77. * @param $params
  78. * @return bool
  79. * @throws \GuzzleHttp\Exception\GuzzleException
  80. * @author Tab
  81. * @date 2021/8/20 16:42
  82. */
  83. public function send($params)
  84. {
  85. try {
  86. if(empty($this->openid)) {
  87. throw new \Exception('openid不存在');
  88. }
  89. $noticeSetting = NoticeSetting::where('scene_id', $params['scene_id'])->findOrEmpty()->toArray();
  90. if ($this->platform == NoticeEnum::OA) {
  91. $sceneConfig = $noticeSetting['oa_notice'];
  92. $sendType = NoticeEnum::OA;
  93. } else {
  94. $sceneConfig = $noticeSetting['mnp_notice'];
  95. $sendType = NoticeEnum::MNP;
  96. }
  97. if ($sceneConfig['template_id'] == '') {
  98. throw new \Exception('模板ID不存在');
  99. } else {
  100. $this->templateId = $sceneConfig['template_id'];
  101. }
  102. if ($this->platform == NoticeEnum::OA) {
  103. $template = $this->oaTemplate($params, $sceneConfig);
  104. } else {
  105. $template = $this->mnpTemplate($params, $sceneConfig);
  106. }
  107. // 添加通知记录
  108. $this->notice = NoticeLogic::addNotice($params, $noticeSetting, $sendType, json_encode($template, JSON_UNESCAPED_UNICODE));
  109. if ($this->platform == NoticeEnum::OA) {
  110. $res = $this->app->template_message->send($template);
  111. } else if ($this->platform == NoticeEnum::MNP) {
  112. $res = $this->app->subscribe_message->send($template);
  113. }
  114. if(isset($res['errcode']) && $res['errcode'] != 0) {
  115. // 发送失败
  116. throw new \Exception(json_encode($res, JSON_UNESCAPED_UNICODE));
  117. }
  118. // 发送成功,记录消息结果
  119. Notice::where('id', $this->notice->id)->update(['extra' => json_encode($res, JSON_UNESCAPED_UNICODE)]);
  120. return true;
  121. } catch (\Exception $e) {
  122. // 记录消息错误信息
  123. if (! empty($this->notice->id)) {
  124. Notice::where('id', $this->notice->id)->update(['extra' => $e->getMessage()]);
  125. }
  126. Log::write("微信消息发送失败:{$e->__toString()}");
  127. return true;
  128. }
  129. }
  130. /**
  131. * @notes 小程序消息模板
  132. * @param $params
  133. * @param $sceneConfig
  134. * @return mixed
  135. * @author Tab
  136. * @date 2021/8/20 15:05
  137. */
  138. public function mnpTemplate($params, $sceneConfig)
  139. {
  140. $tpl = [
  141. 'touser' => $this->openid,
  142. 'template_id' => $this->templateId,
  143. 'page' => $params['page']
  144. ];
  145. return $this->tplformat($sceneConfig, $params, $tpl);
  146. }
  147. /**
  148. * @notes 公众号消息模板
  149. * @param $params
  150. * @param $sceneConfig
  151. * @return array
  152. * @author Tab
  153. * @date 2021/8/20 16:46
  154. */
  155. public function oaTemplate($params, $sceneConfig)
  156. {
  157. $domain = request()->domain();
  158. $tpl = [
  159. 'touser' => $this->openid,
  160. 'template_id' => $this->templateId,
  161. 'url' => $domain.$params['url'],
  162. 'data' => [
  163. 'first' => $sceneConfig['first'],
  164. 'remark' => $sceneConfig['remark']
  165. ]
  166. ];
  167. return $this->tplformat($sceneConfig, $params, $tpl);
  168. }
  169. /**
  170. * @notes 提取并填充微信平台变量
  171. * @param $sceneConfig
  172. * @param $params
  173. * @param $tpl
  174. * @return array
  175. * @author Tab
  176. * @date 2021/8/20 15:33
  177. */
  178. public function tplformat($sceneConfig, $params, $tpl)
  179. {
  180. foreach($sceneConfig['tpl'] as $item) {
  181. foreach($params['params'] as $k => $v) {
  182. $search = '{' . $k . '}';
  183. $item['tpl_content'] = str_replace($search, $v, $item['tpl_content']);
  184. }
  185. $tpl['data'][$item['tpl_keyword']] = $item['tpl_content'];
  186. }
  187. return $tpl;
  188. }
  189. }