Message.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | A3Mall
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2020 http://www.a3-mall.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Author: xzncit <158373108@qq.com>
  8. // +----------------------------------------------------------------------
  9. namespace app\common\library\wechat\mp;
  10. use app\common\library\wechat\Factory;
  11. use app\common\service\wechat\WechatUser;
  12. use mall\utils\Tool;
  13. use think\facade\Db;
  14. use xzncit\core\message\News;
  15. use xzncit\core\message\Raw;
  16. use xzncit\core\message\Text;
  17. use xzncit\core\message\Image as ImageUtils;
  18. class Message {
  19. protected $receive = [];
  20. public function __construct($data){
  21. $this->receive = $data;
  22. }
  23. public function text(){
  24. return $this->keys("wechat_keys#keys#{$this->receive['content']}");
  25. }
  26. public function event(){
  27. switch (strtolower($this->receive['event'])) {
  28. case 'subscribe': // 用户关注
  29. $this->updateFansinfo(true);
  30. if (isset($this->receive['eventkey']) && is_string($this->receive['eventkey'])) {
  31. //扫描带参数二维码事件
  32. if (($key = preg_replace('/^qrscene_/i', '', $this->receive['eventkey']))) {
  33. return $this->keys("wechat_keys#keys#{$key}", false, true);
  34. }
  35. }
  36. return $this->keys('wechat_keys#keys#subscribe', true);
  37. case 'unsubscribe': // 取消关注事件
  38. return $this->updateFansinfo(false);
  39. case 'click': // 关键字事件
  40. return $this->keys("wechat_keys#keys#{$this->receive['eventkey']}");
  41. case 'scancode_push': // 扫码推事件
  42. case 'scancode_waitmsg': // 扫码推事件且弹出“消息接收中”提示框
  43. if (empty($this->receive['scancodeinfo'])) return false;
  44. if (empty($this->receive['scancodeinfo']['scanresult'])) return false;
  45. return $this->keys("wechat_keys#keys#{$this->receive['scancodeinfo']['scanresult']}");
  46. case 'scan': // 用户已关注时的事件推送
  47. if (empty($this->receive['eventkey'])) return false;
  48. return $this->keys("wechat_keys#keys#{$this->receive['eventkey']}");
  49. default:
  50. return false;
  51. }
  52. }
  53. /**
  54. * 关键字处理
  55. * @param string $rule 关键字规则
  56. * @param boolean $isLast 重复回复消息处理
  57. */
  58. private function keys($rule, $isLast = false){
  59. list($table, $field, $value) = explode("#", $rule);
  60. $data = Db::name($table)->where([$field => $value])->find();
  61. if (empty($data["type"]) || (array_key_exists("status", $data) && $data["status"] == 1)) {
  62. return $isLast ? false : $this->keys("wechat_keys#keys#defaults", true);
  63. }
  64. switch (strtolower($data["type"])) {
  65. case "keys":
  66. $content = empty($data["content"]) ? $data["name"] : $data["content"];
  67. return $this->keys("wechat_keys#keys#{$content}", $isLast);
  68. case "text":
  69. return new Text($data['content']);
  70. case 'image':
  71. if (empty($data['image_url']) || !($mediaId = $this->upload(Tool::thumb($data['image_url'],"",true), 'image'))) {
  72. return false;
  73. }
  74. return new ImageUtils($mediaId);
  75. case 'news':
  76. list($news, $articles) = [$this->news($data['news_id']), []];
  77. if (empty($news['articles'])) {
  78. return false;
  79. }
  80. foreach ($news['articles'] as $vo) array_push($articles, [
  81. 'url' => createUrl("api/wechat.news/view", [], false, true) . "?id={$vo['id']}",
  82. 'title' => $vo['title'], 'picurl' => Tool::thumb($vo['local_url'],"",true), 'description' => $vo['digest'],
  83. ]);
  84. return new News($articles);
  85. default:
  86. return new Raw("您要查找的内容不存在");
  87. }
  88. }
  89. /**
  90. * 同步粉丝状态
  91. */
  92. private function updateFansinfo($subscribe = true){
  93. try {
  94. Db::startTrans();
  95. if($subscribe){
  96. $user = Factory::wechat()->user->getUserInfo($this->receive["FromUserName"]);
  97. WechatUser::register($user);
  98. }else{
  99. Db::name("wechat_users")->where([ 'openid' => $this->receive["FromUserName"] ])->update(['subscribe' => '0']);
  100. }
  101. Db::commit();
  102. return true;
  103. }catch (\Exception $ex){
  104. Db::rollback();
  105. return false;
  106. }
  107. }
  108. /**
  109. * 通过图文ID读取图文信息
  110. * @param integer $id 本地图文ID
  111. * @param array $where 额外的查询条件
  112. * @return array
  113. */
  114. private function news($id, $condition = []){
  115. $data = Db::name('wechat_news')->where(['id' => $id])->where($condition)->find();
  116. list($data['articles'], $articleIds) = [[], explode(',', $data['article_id'])];
  117. $articles = Db::name('wechat_news_article')->whereIn('id', $articleIds)->select()->toArray();
  118. foreach ($articleIds as $article_id) {
  119. foreach ($articles as $article) {
  120. if (intval($article['id']) === intval($article_id)) array_push($data['articles'], $article);
  121. unset($article['create_time'], $article['create_time']);
  122. }
  123. }
  124. return $data;
  125. }
  126. private function upload($url, $type = 'image', $videoInfo = []){
  127. $condition = ['md5' => md5($url)];
  128. if (($mediaId = Db::name('wechat_media')->where($condition)->value('media_id'))) {
  129. return $mediaId;
  130. }
  131. $result = Factory::wechat()->materials->add($url,$type,false,$videoInfo);
  132. $data = [
  133. 'local_url' => $url, 'md5' => $condition['md5'], 'type' => $type,
  134. 'media_url' => isset($result['url']) ? $result['url'] : '', 'media_id' => $result['media_id'],
  135. ];
  136. if(Db::name('wechat_media')->where($condition)->count()){
  137. Db::name('wechat_media')->strict(false)->where($condition)->update($data);
  138. }else{
  139. Db::name('wechat_media')->strict(false)->insert($data);
  140. }
  141. return $result['media_id'];
  142. }
  143. }