MessageService.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. <?php
  2. namespace app\common\services;
  3. use app\common\events\message\SendMessageEvent;
  4. use app\common\facades\EasyWeChat;
  5. use app\common\models\AccountWechats;
  6. use app\common\models\Member;
  7. use app\common\models\notice\MessageTemp;
  8. use app\common\models\TemplateMessageRecord;
  9. use app\Jobs\DispatchesJobs;
  10. use app\Jobs\MessageNoticeJob;
  11. use Exception;
  12. use app\Jobs\MiniMessageNoticeJob;
  13. use app\common\models\FormId;
  14. class MessageService
  15. {
  16. /**
  17. * 消息推送,暂时使用,需要优化
  18. *
  19. * @param int $member_id
  20. * @param int $template_id
  21. * @param array $params
  22. * @param string $url
  23. * @return bool
  24. */
  25. public function push($member_id, $temp_id, array $params, $url='', $uniacid='')
  26. {
  27. if ($uniacid) {
  28. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = $uniacid;
  29. } else{
  30. \Setting::$uniqueAccountId = \YunShop::app()->uniacid;
  31. }
  32. if(\Setting::get('shop.notice.toggle') == false){
  33. return false;
  34. }
  35. if (!$member_id || !$temp_id) {
  36. return false;
  37. }
  38. $temp = MessageTemp::withoutGlobalScopes(['uniacid'])->whereId($temp_id)->first();
  39. if (!$temp) {
  40. return false;
  41. }
  42. $template_id = $temp->template_id;
  43. if (!$template_id) {
  44. \Log::error("微信消息推送:MessageTemp::template_id参数不存在");
  45. return false;
  46. }
  47. $send_msg = $this->getSendMsg($temp, $params);
  48. $memberModel = $this->getMemberModel($member_id);
  49. if (!$memberModel) {
  50. return false;
  51. }
  52. $config = $this->getConfiguration($uniacid);
  53. try {
  54. if(empty($url)){
  55. $url = $temp->news_link;//todo 没有链接就是用模板设置的链接
  56. }
  57. $app = EasyWeChat::officialAccount($config);
  58. $userService = $app->user;
  59. $user = $userService->get($memberModel->hasOneFans->openid);
  60. if ($user['subscribe'] != 1 && $user->subscribe != 1) {
  61. \Log::debug('微信消息推送:用户未关注公众号',$user);
  62. return false;
  63. }
  64. $app->template_message->send([
  65. 'touser' => $memberModel->hasOneFans->openid,
  66. 'template_id' => $template_id,
  67. 'url' => $url,
  68. 'data' => $send_msg,
  69. ]);
  70. } catch (Exception $error) {
  71. TemplateMessageRecord::create([
  72. 'uniacid' => \YunShop::app()->uniacid,
  73. 'member_id' => $member_id,
  74. 'template_id' => $template_id,
  75. 'url' => $url?:'无',
  76. 'openid' => $memberModel->hasOneFans->openid ?: 0,
  77. 'data' => json_encode($send_msg),
  78. 'send_time' => time(),
  79. 'status' => -1,
  80. 'extend_data' => $error->getMessage(),
  81. ]);
  82. return true;
  83. }
  84. return true;
  85. }
  86. /**
  87. * 会员信息
  88. *
  89. * @param $member_id
  90. * @return bool
  91. */
  92. private function getMemberModel($member_id)
  93. {
  94. if (!$member_id) {
  95. \Log::error("微信消息推送:uid参数不存在");
  96. return false;
  97. }
  98. $memberModel = Member::whereUid($member_id)->with([
  99. 'hasOneFans' => function($q) {
  100. $q->uniacid();
  101. }])->first();
  102. if (!isset($memberModel)) {
  103. \Log::error("微信消息推送:未找到uid:{$member_id}的用户");
  104. return false;
  105. }
  106. if (!$memberModel->isFollow()) {
  107. \Log::error("微信消息推送:会员uid:{$member_id}未关注公众号");
  108. return false;
  109. }
  110. if (!$memberModel->hasOneFans->openid) {
  111. \Log::error("微信消息推送:会员uid:{$member_id} 没有openid");
  112. return false;
  113. }
  114. return $memberModel;
  115. }
  116. /**
  117. * 获取公众号配置信息
  118. *
  119. * @return array|bool
  120. */
  121. public function getConfiguration($uniacid)
  122. {
  123. if ($uniacid) {
  124. \Setting::$uniqueAccountId = \YunShop::app()->uniacid = $uniacid;
  125. } else{
  126. \Setting::$uniqueAccountId = \YunShop::app()->uniacid;
  127. }
  128. $accountWechat = AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid);
  129. if (!isset($accountWechat)) {
  130. \Log::error("微信消息推送:未找到uniacid:{$uniacid}的配置信息");
  131. return false;
  132. }
  133. return ['app_id' => $accountWechat->key, 'secret' => $accountWechat->secret];
  134. }
  135. private function getSendMsg($temp, $params)
  136. {
  137. $msg = [
  138. 'first' => [
  139. 'value' => $this->replaceTemplate($temp->first, $params),
  140. 'color' => $temp->first_color
  141. ],
  142. 'remark' => [
  143. 'value' => $this->replaceTemplate($temp->remark, $params),
  144. 'color' => $temp->remark_color
  145. ]
  146. ];
  147. foreach ($temp->data as $row) {
  148. $msg[$row['keywords']] = [
  149. 'value' => $this->replaceTemplate($row['value'], $params),
  150. 'color' => $row['color']
  151. ];
  152. }
  153. return $msg;
  154. }
  155. private function replaceTemplate($str, $datas = array())
  156. {
  157. foreach ($datas as $row ) {
  158. $str = str_replace('[' . $row['name'] . ']', $row['value'], $str);
  159. }
  160. return $str;
  161. }
  162. /*todo 一下代码需要重构,重新分化类功能 2018-03-23 yitian*/
  163. /**
  164. * 发送微信模板消息
  165. *
  166. * @param $templateId
  167. * @param $data
  168. * @param $uid
  169. * @param string $uniacid
  170. * @param string $url
  171. * @return bool
  172. */
  173. public static function MiniNotice($templateId, $data, $uid, $uniacid = '', $url = '',$scene = '')
  174. {
  175. \Log::debug('==============miniApp===================',[$templateId,$data,$uid]);
  176. // $res = AccountWechats::getAccountByUniacid(\YunShop::app()->uniacid);
  177. $res = \Setting::get('plugin.min_app');
  178. $options = [
  179. 'app_id' => $res['key'],
  180. 'secret' => $res['secret'],
  181. ];
  182. $member = Member::whereUid($uid)->first();
  183. if (!isset($member)) {
  184. \Log::error("小程序消息推送失败,未找到uid:{$uid}的用户");
  185. return false;
  186. }
  187. if(empty($scene)){
  188. $createTime = $member->hasOneMiniApp->formId_create_time;
  189. $time=strtotime (date("Y-m-d H:i:s")); //当前时间
  190. $minute=floor(($time-$createTime) % (86400/60));
  191. \Log::info('小程序消息推送时间',$createTime."----".$time."----".$minute);
  192. if ($minute > 10080 && empty($createTime)){
  193. \Log::error("小程序消息推送失败,formId失效");
  194. return false;
  195. }
  196. // $scene = $member->hasOneMiniApp->formId;
  197. // $pieces = explode("#", $scene);
  198. // $scene = array_shift($pieces);//获取首个元素并删除
  199. // $str = implode("#", $pieces);
  200. // MemberMiniAppModel::where('member_id',$uid)->uniacid()->update(['formId'=>$str]);
  201. $scene = FormId::orderBy('addtime','desc')->first();
  202. $scene = empty($scene) ? array() : $scene->toArray();
  203. \Log::info('小程序scene',$scene);
  204. }
  205. \Log::info('小程序消息scene',$scene);
  206. if(empty($scene)){
  207. \Log::error("小程序消息推送失败,formId失效");
  208. return false;
  209. }
  210. $job = new MiniMessageNoticeJob($options, $templateId, $data,$member->hasOneMiniApp->openid, $url,$scene['formid'] );
  211. DispatchesJobs::dispatch($job,DispatchesJobs::LOW);
  212. FormId::where('id',$scene['id'])->delete();//删除formid减少消耗
  213. }
  214. public static function notice($templateId, $data, $uid, $uniacid = '', $url = '',$miniApp = [])
  215. {
  216. if (\Setting::get('shop.notice.toggle') == false) {
  217. return false;
  218. }
  219. $member = Member::whereUid($uid)->first();
  220. if (!isset($member)) {
  221. \Log::error("微信消息推送失败,未找到uid:{$uid}的用户");
  222. return false;
  223. }
  224. if (!$member->isFollow()) {
  225. return false;
  226. }
  227. $job = new MessageNoticeJob($templateId, $data, $member->hasOneFans->openid, $url);
  228. DispatchesJobs::dispatch($job,DispatchesJobs::LOW);
  229. }
  230. public static function getWechatTemplates()
  231. {
  232. $app = app('wechat');
  233. $notice = $app->notice;
  234. return $notice->getPrivateTemplates();
  235. }
  236. /**
  237. * 验证"模板消息ID" 是否有效
  238. * @param $template_id
  239. * @return array
  240. */
  241. public static function verifyTemplateId($template_id)
  242. {
  243. $templates = self::getWechatTemplates()->get('template_list');
  244. if (!isset($templates)) {
  245. return [
  246. 'status' => -1,
  247. 'msg' => '任务处理通知模板id错误'
  248. ];
  249. }
  250. $template = collect($templates)->where('template_id', $template_id)->first();
  251. if (!isset($template)) {
  252. return [
  253. 'status' => -1,
  254. 'msg' => '任务处理通知模板id错误'
  255. ];
  256. }
  257. return [
  258. 'status' => 1
  259. ];
  260. }
  261. /**
  262. * 发送微信"客服消息"
  263. * @param $openid
  264. * @param $data
  265. * 文本消息: $data = new Text(['content' => 'Hello']);
  266. * 图文消息:
  267. * $data = new News([
  268. * 'title' => 'your_title',
  269. * 'image' => 'your_image',
  270. * 'description' => 'your_description',
  271. * 'url' => 'your_url',
  272. * ]);
  273. */
  274. public static function sendCustomerServiceNotice($openid, $data)
  275. {
  276. $app = app('wechat');
  277. if (array_key_exists('content', $data)) {
  278. $data = new Text($data); //发送文本消息
  279. } else {
  280. $data = new News($data); //发送图文消息
  281. }
  282. $app->staff->message($data)->to($openid)->send();
  283. }
  284. }