WechatBasisLogic.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?php
  2. /**
  3. * 易优CMS
  4. * ============================================================================
  5. * 版权所有 2016-2028 海南赞赞网络科技有限公司,并保留所有权利。
  6. * 网站地址: http://www.eyoucms.com
  7. * ----------------------------------------------------------------------------
  8. * 如果商业用途务必到官方购买正版授权, 以免引起不必要的法律纠纷.
  9. * ============================================================================
  10. * Author: 小虎哥 <1105415366@qq.com>
  11. * Date: 2018-4-3
  12. */
  13. namespace app\plugins\logic;
  14. use think\Model;
  15. use think\Db;
  16. use app\plugins\util\WechatBasisUtil;
  17. /**
  18. * 逻辑定义
  19. * Class WechatBasisLogic
  20. */
  21. class WechatBasisLogic extends Model
  22. {
  23. public $config;
  24. public $baseObj;
  25. public $messagesObj;
  26. public $msg_serviceObj;
  27. public $materialObj;
  28. public $userObj;
  29. public $basisUtil;
  30. public function __construct($config){
  31. vendor('wechat.wechat');
  32. $this->config = $config;
  33. /* 微信公众平台类 */
  34. $this->baseObj = $this->getClassObj('base');
  35. $this->messagesObj = $this->getClassObj('messages');
  36. $this->msg_serviceObj = $this->getClassObj('messages_service');
  37. $this->materialObj = $this->getClassObj('material');
  38. $this->userObj = $this->getClassObj('user');
  39. $this->basisUtil = new WechatBasisUtil($this->config);
  40. }
  41. public function getClassObj($className)
  42. {
  43. $class = '\\'.$className; //
  44. return new $class($this->config); //实例化对应的类
  45. }
  46. /**
  47. * 获取access_token
  48. */
  49. public function get_access_token()
  50. {
  51. return $this->baseObj->access_token;
  52. }
  53. /**
  54. * 响应消息
  55. */
  56. public function responseMsg()
  57. {
  58. /* 消息类 */
  59. $postStr = file_get_contents("php://input");
  60. if (!empty($postStr)){
  61. // $this->messagesObj->logger("R \r\n".$postStr);
  62. $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
  63. $RX_TYPE = trim($postObj->MsgType);
  64. // 关于重试的消息排重
  65. if ($RX_TYPE == "event") { // 事件类型消息推荐使用FromUserName + CreateTime 排重
  66. if ($postObj->Event == "subscribe" || $postObj->Event == "unsubscribe") {
  67. $eventmsg_val = md5($postObj->FromUserName.$postObj->CreateTime);
  68. $eventmsg_list = cache('basis_eventmsg_list');
  69. $eventmsg_list = ($eventmsg_list == false) ? array() : $eventmsg_list;
  70. if ($eventmsg_list && in_array($eventmsg_val, $eventmsg_list)) {
  71. exit('success');
  72. } else {
  73. array_push($eventmsg_list, $eventmsg_val);
  74. cache('basis_eventmsg_list', $eventmsg_list, 1800);
  75. }
  76. }
  77. } else { // 有msgid的消息推荐使用msgid排重
  78. $msg_id = (string)$postObj->MsgId;
  79. $msgid_list = cache('basis_msgid_list');
  80. $msgid_list = ($msgid_list == false) ? array() : $msgid_list;
  81. if ($msgid_list && in_array($msg_id, $msgid_list)) {
  82. exit('success');
  83. } else {
  84. array_push($msgid_list, $msg_id);
  85. cache('basis_msgid_list', $msgid_list, 1800);
  86. }
  87. }
  88. // $this->messagesObj->logger("R \r\n".var_export($postObj,true));
  89. //消息类型分离
  90. switch ($RX_TYPE)
  91. {
  92. // 事件
  93. case "event":
  94. $result = $this->receiveEvent($postObj);
  95. break;
  96. // 文本
  97. case "text":
  98. $result = $this->receiveText($postObj);
  99. break;
  100. // 图片
  101. case "image":
  102. $result = $this->receiveImage($postObj);
  103. break;
  104. // 地理位置
  105. case "location":
  106. $result = $this->receiveLocation($postObj);
  107. break;
  108. // 语音
  109. case "voice":
  110. $result = $this->receiveVoice($postObj);
  111. break;
  112. // 视频
  113. case "video":
  114. $result = $this->receiveVideo($postObj);
  115. break;
  116. // 链接
  117. case "link":
  118. $result = $this->receiveLink($postObj);
  119. break;
  120. default:
  121. $result = "unknown msg type: ".$RX_TYPE;
  122. break;
  123. }
  124. // $this->messagesObj->logger("T \r\n".$result);
  125. echo $result;
  126. }else {
  127. echo "";
  128. exit;
  129. }
  130. }
  131. /**
  132. * 接收事件消息
  133. */
  134. public function receiveEvent($object)
  135. {
  136. $content = "";
  137. switch ($object->Event)
  138. {
  139. // 关注时的事件推送
  140. case "subscribe":
  141. $row = M('weapp_wx_subscribe')->where('token', $this->config['token'])->find();
  142. if (!empty($row)) {
  143. if ('TEXT' == $row['type']) {
  144. $this->msg_serviceObj->sendServiceText($object, $row['text']);
  145. $result = 'success';
  146. } else if ('PIC' == $row['type']) {
  147. $content = array("MediaId"=>$row['media_id']);
  148. $result = $this->messagesObj->transmitImage($object, $content);
  149. }
  150. }
  151. // $result = $this->handleSubscribeEvent($object);
  152. return $result;
  153. break;
  154. // 取消关注事件
  155. case "unsubscribe":
  156. $content = "取消关注";
  157. break;
  158. // 点击菜单拉取消息时的事件推送
  159. case "CLICK":
  160. $object->Content = $object->EventKey;
  161. exit($this->receiveText($object));
  162. break;
  163. // 点击菜单跳转链接时的事件推送
  164. case "VIEW":
  165. // $this->msg_serviceObj->sendServiceText($object, "点击菜单跳转链接时的事件推送 ".$object->EventKey);
  166. // $content = "跳转链接 ".$object->EventKey;
  167. break;
  168. // 扫描带参数二维码场景,用户已关注时的事件推送
  169. case "SCAN":
  170. $content = "扫描场景 ".$object->EventKey;
  171. $result = $this->handleSubscribeEvent($object);
  172. return $result;
  173. break;
  174. // 上报地理位置事件(此功能要开启获取用户地理位置的接口,可以设置用户进行对话时上报一次,或者用户进行对话后每隔5s上报一次)
  175. case "LOCATION":
  176. $content = "上传位置:纬度 ".$object->Latitude.";经度 ".$object->Longitude;
  177. break;
  178. // 扫码推事件且弹出“消息接收中”提示框的事件推送
  179. case "scancode_waitmsg":
  180. if ($object->ScanCodeInfo->ScanType == "qrcode"){
  181. $content = "扫码带提示:类型 二维码 结果:".$object->ScanCodeInfo->ScanResult;
  182. }else if ($object->ScanCodeInfo->ScanType == "barcode"){
  183. $codeinfo = explode(",",strval($object->ScanCodeInfo->ScanResult));
  184. $codeValue = $codeinfo[1];
  185. $content = "扫码带提示:类型 条形码 结果:".$codeValue;
  186. }else{
  187. $content = "扫码带提示:类型 ".$object->ScanCodeInfo->ScanType." 结果:".$object->ScanCodeInfo->ScanResult;
  188. }
  189. break;
  190. // 扫码推事件的事件推送
  191. case "scancode_push":
  192. $content = "扫码推事件";
  193. break;
  194. // 弹出系统拍照发图的事件推送
  195. case "pic_sysphoto":
  196. $content = "系统拍照";
  197. break;
  198. // 弹出微信相册发图器的事件推送
  199. case "pic_weixin":
  200. $content = "相册发图:数量 ".$object->SendPicsInfo->Count;
  201. break;
  202. // 弹出拍照或者相册发图的事件推送
  203. case "pic_photo_or_album":
  204. $content = "拍照或者相册:数量 ".$object->SendPicsInfo->Count;
  205. break;
  206. // 弹出地理位置选择器的事件推送
  207. case "location_select":
  208. $content = "发送位置:标签 ".$object->SendLocationInfo->Label;
  209. break;
  210. default:
  211. $content = "receive a new event: ".$object->Event;
  212. break;
  213. }
  214. if(is_array($content)){
  215. if (isset($content[0]['PicUrl'])){
  216. $result = $this->messagesObj->transmitNews($object, $content);
  217. }else if (isset($content['MusicUrl'])){
  218. $result = $this->messagesObj->transmitMusic($object, $content);
  219. }
  220. }else{
  221. $result = $this->messagesObj->transmitText($object, $content);
  222. }
  223. return $result;
  224. }
  225. /**
  226. * 接收文本消息
  227. */
  228. public function receiveText($object)
  229. {
  230. $keyword = trim($object->Content);
  231. $content = $this->basisUtil->getKeywordContent($keyword);
  232. //将消息转发到客服系统
  233. /* if (preg_match('/(在吗)|(客服)/i', $keyword)) {
  234. $this->msg_serviceObj->sendServiceText($object, '这是客服自动回复的消息_1');
  235. $result = $this->msg_serviceObj->transmitService($object);
  236. return $result;
  237. } else if (strstr($keyword, "表情")){
  238. $content = "中国:".$this->messagesObj->bytes_to_emoji(0x1F1E8).$this->messagesObj->bytes_to_emoji(0x1F1F3)."\n仙人掌:".$this->messagesObj->bytes_to_emoji(0x1F335);
  239. }else if (strstr($keyword, "测试图片")){
  240. // 上传临时素材接口
  241. $pic = ROOT_PATH.'public/static/common/images/bag-imgB.jpg';
  242. $params = $this->materialObj->mediaUpload($pic);
  243. $content = array("MediaId"=>$params['media_id']);
  244. } else if (strstr($keyword, "关注")) {
  245. $this->msg_serviceObj->sendServiceText($object, '这是客服自动回复的消息_1');
  246. $this->msg_serviceObj->sendServiceText($object, '这是客服自动回复的消息_2');
  247. $result = $this->handleSubscribeEvent($object);
  248. return $result;
  249. }else if (strstr($keyword, "音乐")){
  250. $content = array();
  251. $content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3", "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3");
  252. }*/
  253. /* if ($content == false) {
  254. $content = "亲,有什么能帮助您的吗?\n欢迎咨询官网客服,感谢支持!";
  255. }*/
  256. if(is_array($content)){
  257. if (isset($content[0])){
  258. $result = $this->messagesObj->transmitNews($object, $content);
  259. }else if (isset($content['MusicUrl'])){
  260. $result = $this->messagesObj->transmitMusic($object, $content);
  261. }else if (isset($content['MediaId'])){
  262. $result = $this->messagesObj->transmitImage($object, $content);
  263. }
  264. }else{
  265. $result = $this->messagesObj->transmitText($object, $content);
  266. }
  267. return $result;
  268. }
  269. /**
  270. * 接收图片消息
  271. */
  272. private function receiveImage($object)
  273. {
  274. $content = array("MediaId"=>$object->MediaId);
  275. $result = $this->messagesObj->transmitImage($object, $content);
  276. return $result;
  277. }
  278. /**
  279. * 接收位置消息
  280. */
  281. private function receiveLocation($object)
  282. {
  283. $content = "你发送的是位置,经度为:".$object->Location_Y.";纬度为:".$object->Location_X.";缩放级别为:".$object->Scale.";位置为:".$object->Label;
  284. $result = $this->messagesObj->transmitText($object, $content);
  285. return $result;
  286. }
  287. /**
  288. * 接收语音消息
  289. */
  290. private function receiveVoice($object)
  291. {
  292. if (isset($object->Recognition) && !empty($object->Recognition)){
  293. $content = "你刚才说的是:".$object->Recognition;
  294. $result = $this->messagesObj->transmitText($object, $content);
  295. }else{
  296. $content = array("MediaId"=>$object->MediaId);
  297. $result = $this->messagesObj->transmitVoice($object, $content);
  298. }
  299. return $result;
  300. }
  301. /**
  302. * 接收视频消息
  303. */
  304. private function receiveVideo($object)
  305. {
  306. $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");
  307. $result = $this->messagesObj->transmitVideo($object, $content);
  308. return $result;
  309. }
  310. /**
  311. * 接收链接消息
  312. */
  313. private function receiveLink($object)
  314. {
  315. $content = "你发送的是链接,标题为:".$object->Title.";内容为:".$object->Description.";链接地址为:".$object->Url;
  316. $result = $this->messagesObj->transmitText($object, $content);
  317. return $result;
  318. }
  319. /**
  320. * 处理关注事件
  321. * @param object $object
  322. * @return string
  323. */
  324. public function handleSubscribeEvent($object)
  325. {
  326. $begin = time();
  327. /* 获取表单数据(来自带参数的二维码) */
  328. $ticket_data = $this->basisUtil->convert_ticket_data($object);
  329. /* 获得openId值 */
  330. $openid = $object->FromUserName;
  331. /* 获取用户基本信息 */
  332. $user_info = $this->userObj->get_user_info($openid);
  333. $headimgurl = preg_replace('/\/\d$/i', '/132', $user_info['headimgurl']);
  334. /* 给背景图片添加图片水印、文字水印,生成新的海报 */
  335. $image_sy = array(
  336. array(
  337. 'src_path'=>$headimgurl,
  338. 'src_w'=>0,
  339. 'src_h'=>0,
  340. 'locate'=>array(415, 137),
  341. 'alpha'=>100,
  342. 'info_bg'=>array(),
  343. ),
  344. );
  345. $text_sy = array();
  346. $company_arr = array(
  347. 'text'=>isset($ticket_data['company'])?$ticket_data['company']:'', // 文案
  348. 'fontfile'=>'hgzb.ttf', // 字体文件
  349. 'size'=>28, // 字体大小
  350. 'color'=>'#fccfb5', // 字体颜色
  351. 'locate'=>10, // 文字写入位置
  352. 'offset'=>array(0, 0), // 文字相对当前位置的偏移量
  353. 'angle'=>0, // 文字倾斜角度
  354. 'info_bg'=>array('width'=>415, 'height'=>137),
  355. );
  356. array_push($text_sy, $company_arr);
  357. $name_arr = array(
  358. 'text'=>isset($form_data['name'])?$form_data['name']:$user_info['nickname'], // 文案
  359. 'fontfile'=>'hgzb.ttf', // 字体文件
  360. 'size'=>28, // 字体大小
  361. 'color'=>'#fccfb5', // 字体颜色
  362. 'locate'=>10, // 文字写入位置
  363. 'offset'=>array(0, 50), // 文字相对当前位置的偏移量
  364. 'angle'=>0, // 文字倾斜角度
  365. 'info_bg'=>array('width'=>415, 'height'=>137),
  366. );
  367. array_push($text_sy, $name_arr);
  368. $mobile_arr = array(
  369. 'text'=>isset($ticket_data['mobile'])?$ticket_data['mobile']:'139xxxxxx72', // 文案
  370. 'fontfile'=>'hgzb.ttf', // 字体文件
  371. 'size'=>28, // 字体大小
  372. 'color'=>'#fccfb5', // 字体颜色
  373. 'locate'=>10, // 文字写入位置
  374. 'offset'=>array(0, 100), // 文字相对当前位置的偏移量
  375. 'angle'=>0, // 文字倾斜角度
  376. 'info_bg'=>array('width'=>415, 'height'=>137),
  377. );
  378. array_push($text_sy, $mobile_arr);
  379. $path_bg = ROOT_PATH.'public/static/common/images/bag-imgB.jpg';
  380. $watermarkObj = $this->getClassObj('watermark');
  381. $pic = $watermarkObj->addWatermark($path_bg, $image_sy, $text_sy);
  382. /* 上传临时素材接口 */
  383. $params = $this->materialObj->mediaUpload($pic);
  384. if (isset($params['errcode'])) {
  385. $content = $params['errmsg'];
  386. $result = $this->messagesObj->transmitText($object, $content);
  387. } else {
  388. // 临时素材的media_id
  389. $media_id = $params['media_id'];
  390. $this->msg_serviceObj->sendServiceImage($object, $media_id);
  391. // $end = time();
  392. // $content = '耗时:'.($end - $begin).'秒……之后回复图片';
  393. // $msg_serviceObj->sendServiceText($object, $content);
  394. }
  395. return 'success';
  396. }
  397. }