OaMessage.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. <?php
  2. /**
  3. * OaMessage.php UTF-8
  4. * 公众号消息
  5. *
  6. * @date : 2018/9/26 15:16
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HuoMp 1.0
  11. */
  12. namespace huoMpMsg\controller;
  13. use huo\controller\member\Oauth;
  14. use huo\controller\request\Channel;
  15. use huo\controller\request\Device;
  16. use huo\controller\request\Game;
  17. use huo\controller\request\Mem;
  18. use huo\model\member\MemoauthModel;
  19. use huolib\constant\MemConst;
  20. use huolib\constant\OauthConst;
  21. use huolib\constant\WeiXinMenuConst;
  22. use huomp\model\weixin\MpConfModel;
  23. use huoMpMsg\constant\OfficialAccountConst;
  24. use huoMpMsg\model\MpEventMsgLogModel;
  25. use huoMpMsg\model\MpMsgLogModel;
  26. use think\Log;
  27. class OaMessage {
  28. /**
  29. * 接收微信数据
  30. * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453
  31. *
  32. * @param string $mp_id 小程序ID
  33. * @param array $param
  34. *
  35. */
  36. public function receive($mp_id, $param) {
  37. $_data['mp_id'] = $mp_id;
  38. $_data['wx_msg_id'] = get_val($param, 'MsgId', 0);
  39. $_data['source_id'] = get_val($param, 'ToUserName', '');
  40. $_data['open_id'] = get_val($param, 'FromUserName', '');
  41. $_data['msg_type'] = get_val($param, 'MsgType', '');
  42. $_data['pic_url'] = get_val($param, 'PicUrl', '');
  43. $_data['media_id'] = get_val($param, 'MediaId', '');
  44. $_data['title'] = get_val($param, 'Title', '');
  45. $_data['mini_app_id'] = get_val($param, 'AppId', '');
  46. $_data['page_path'] = get_val($param, 'PagePath', '');
  47. $_data['thumb_url'] = get_val($param, 'ThumbUrl', '');
  48. $_data['thumb_media_id'] = get_val($param, 'ThumbMediaId', '');
  49. $_data['text'] = get_val($param, 'Content', '');
  50. $_data['wx_create_time'] = get_val($param, 'CreateTime', 0);
  51. $_model = new MpMsgLogModel();
  52. $_rs = $_model->hasMsg($_data['wx_msg_id']);
  53. if (empty($_rs)) {
  54. $_rs = $_model->insertLog($_data);
  55. }
  56. if (false !== $_rs) {
  57. if (!empty($_data['text'])) {
  58. $_msg = (new OaReturnMsg())->getKeyReturnMsg($mp_id, $_data['text']);
  59. if (!empty($_msg)) {
  60. $this->sendTextMsg($mp_id, $_data['open_id'], $_msg);
  61. }
  62. }
  63. // $this->sendTextMsg($mp_id,$_data['open_id'],'您好');
  64. die('success');
  65. }
  66. die('');
  67. }
  68. /**
  69. * 接收事件推送
  70. * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454
  71. *
  72. * @param string $mp_id 微信ID
  73. * @param array $param 参数
  74. *
  75. */
  76. public function receiveEventMsg($mp_id, $param) {
  77. if (empty($mp_id)
  78. || empty($param)
  79. || empty($param['Event'])) {
  80. return;
  81. }
  82. $_event = $param['Event'];
  83. $_data['mp_id'] = $mp_id;
  84. $_data['source_id'] = get_val($param, 'ToUserName', '');
  85. $_data['open_id'] = get_val($param, 'FromUserName', '');
  86. $_data['msg_type'] = get_val($param, 'MsgType', '');
  87. $_data['event'] = get_val($param, 'Event', '');
  88. $_data['event_key'] = json_encode(get_val($param, 'EventKey', []));
  89. $_data['ticket'] = get_val($param, 'Ticket', '');
  90. $_data['latitude'] = get_val($param, 'Latitude', '');
  91. $_data['longitude'] = get_val($param, 'Longitude', '');
  92. $_data['precision'] = get_val($param, 'Precision', '');
  93. $_data['wx_create_time'] = get_val($param, 'CreateTime', 0);
  94. $_model = new MpEventMsgLogModel();
  95. $_rs = $_model->hasMsg($_data['open_id'], $_data['wx_create_time']);
  96. if (empty($_rs)) {
  97. $_model->insertLog($_data);
  98. }
  99. switch ($_event) {
  100. case OfficialAccountConst::EVENT_SUBSCRIBE:
  101. $_event_key = get_val($param, 'EventKey', '');
  102. if (!empty($_event_key)) {
  103. /* 扫描带参数二维码事件 用户未关注时,进行关注后的事件推送 */
  104. break;
  105. }
  106. /* 关注事件 */
  107. $this->subscribe($mp_id, $param);
  108. break;
  109. case OfficialAccountConst::EVENT_UNSUBSCRIBE:
  110. /* 取消关注事件 */
  111. $this->unsubscribe($mp_id, $param);
  112. break;
  113. case OfficialAccountConst::EVENT_SCAN:
  114. /* 扫描带参数二维码事件 用户已关注时的事件推送 */
  115. $this->scan($mp_id, $param);
  116. break;
  117. case OfficialAccountConst::EVENT_CLICK:
  118. /* 自定义菜单事件 点击菜单拉取消息时的事件推送 */
  119. $this->click($mp_id, $param);
  120. break;
  121. case OfficialAccountConst::EVENT_VIEW:
  122. /* 自定义菜单事件 点击菜单跳转链接时的事件推送 */
  123. $this->view($mp_id, $param);
  124. break;
  125. case OfficialAccountConst::EVENT_SCANCODE_PUSH:
  126. /* 扫码推事件的事件推送 */
  127. $this->scanCodePush($mp_id, $param);
  128. break;
  129. case OfficialAccountConst::EVENT_SCANCODE_WAITMSG:
  130. /* 扫码推事件且弹出“消息接收中”提示框的事件推送 */
  131. $this->scanCodeWaitmsg($mp_id, $param);
  132. break;
  133. case OfficialAccountConst::EVENT_PIC_SYSPHOTO:
  134. /* 弹出系统拍照发图的事件推送 */
  135. $this->picSysPhoto($mp_id, $param);
  136. break;
  137. case OfficialAccountConst::EVENT_PIC_PHOTO_OR_ALBUM:
  138. /* 弹出拍照或者相册发图的事件推送 */
  139. $this->picPhotoOrAlbum($mp_id, $param);
  140. break;
  141. case OfficialAccountConst::EVENT_PIC_WEIXIN:
  142. /* 弹出微信相册发图器的事件推送 */
  143. $this->picWeixin($mp_id, $param);
  144. break;
  145. case OfficialAccountConst::EVENT_LOCATION_SELECT:
  146. /* 弹出微信相册发图器的事件推送 */
  147. $this->locationSelect($mp_id, $param);
  148. break;
  149. default:
  150. break;
  151. }
  152. }
  153. /**
  154. *
  155. * 用户在关注与取消关注公众号时,微信会把这个事件推送到开发者填写的URL。方便开发者给用户下发欢迎消息或者做帐号的解绑。为保护用户数据隐私,开发者收到用户取消关注事件时需要删除该用户的所有信息。
  156. *
  157. * @param string $mp_id 微信ID
  158. * @param array $param 参数
  159. *
  160. *
  161. * ToUserName 开发者微信号
  162. * FromUserName 发送方帐号(一个OpenID)
  163. * CreateTime 消息创建时间 (整型)
  164. * MsgType 消息类型,event
  165. * Event 事件类型,subscribe(订阅)、unsubscribe(取消订阅)
  166. */
  167. public function subscribe($mp_id, $param) {
  168. $_open_id = get_val($param, 'FromUserName', '');
  169. if (empty($_open_id)) {
  170. die('');
  171. }
  172. $_conf_id = (new MpConfModel())->getIdByMpId($mp_id);
  173. if (empty($_conf_id)) {
  174. die('');
  175. }
  176. $_mo_model = new MemoauthModel();
  177. $_type = OauthConst::OAUTH_WEIXIN;
  178. $_mo_data = $_mo_model->getInfoByOpenId($_type, $_open_id);
  179. if (empty($_mo_data)) {
  180. /* 注册用户 */
  181. $_game_rq = new Game();
  182. $_channel_rq = new Channel();
  183. $_device_rq = new Device();
  184. $_mem_rq = new Mem();
  185. $_oauth_data['token'] = [];
  186. $_oauth_data['app_key'] = $mp_id;
  187. $_oauth_data['openid'] = $_open_id;
  188. $_oauth_data['unionid'] = $_open_id;
  189. $_oauth_data['channel'] = $_type;
  190. $_oauth_data['nickname'] = '';
  191. $_oauth_data['gender'] = '';
  192. $_oauth_data['avatar'] = '';
  193. $_oauth_data['token'] = ['openid' => $_open_id, 'access_token' => '', 'expires_in' => 0];
  194. $_config = [];
  195. $_wx_app_secret = (new MpConfModel())->getSecretByMpId($mp_id);
  196. if (!empty($_wx_app_secret)) {
  197. $_config['APP_KEY'] = $mp_id;
  198. $_config['APP_SECRET'] = $_wx_app_secret;
  199. $_config['CALLBACK'] = '';
  200. }
  201. (new Oauth())->oAuthReg(
  202. $_type, $_oauth_data, $_game_rq, $_channel_rq, $_device_rq, $_mem_rq, $_config
  203. );
  204. } else {
  205. /* 更新第三方状态 */
  206. $_mo_data['status'] = MemConst::STATUS_NORMAL;
  207. $_mo_model->updateOauth($_mo_data['from'], $_open_id, $_mo_data);
  208. }
  209. $_msg = (new OaReturnMsg())->getSubscribeMsg($mp_id);
  210. if (empty($_msg)) {
  211. $_msg = '欢迎关注!';
  212. }
  213. $this->sendTextMsg($mp_id, $_open_id, $_msg);
  214. die('success');
  215. }
  216. public function unsubscribe($mp_id, $param) {
  217. $_open_id = get_val($param, 'FromUserName', '');
  218. if (empty($_open_id)) {
  219. die('');
  220. }
  221. $_conf_id = (new MpConfModel())->getIdByMpId($mp_id);
  222. if (empty($_conf_id)) {
  223. die('');
  224. }
  225. $_mo_model = new MemoauthModel();
  226. $_type = OauthConst::OAUTH_WEIXIN;
  227. $_mo_data = $_mo_model->getInfoByOpenId($_type, $_open_id);
  228. if (!empty($_mo_data)) {
  229. $_mo_data['status'] = MemConst::STATUS_TRY;
  230. $_mo_model->updateOauth($_type, $_open_id, $_mo_data);
  231. }
  232. die('');
  233. }
  234. public function scan($mp_id, $param) {
  235. $_open_id = get_val($param, 'FromUserName', '');
  236. if (empty($_open_id)) {
  237. die('');
  238. }
  239. }
  240. public function click($mp_id, $param) {
  241. $_open_id = get_val($param, 'FromUserName', '');
  242. if (empty($_open_id)) {
  243. die('');
  244. }
  245. $_key = get_val($param, 'EventKey', '');
  246. if (empty($_key)) {
  247. die('');
  248. }
  249. $_msg = (new OaReturnMsg())->getKeyReturnMsg($mp_id, $_key, WeiXinMenuConst::IS_MENU_2);
  250. if (!empty($_msg)) {
  251. $this->sendTextMsg($mp_id, $_open_id, $_msg);
  252. die('success');
  253. }
  254. }
  255. public function view($mp_id, $param) {
  256. $_open_id = get_val($param, 'FromUserName', '');
  257. if (empty($_open_id)) {
  258. die('');
  259. }
  260. }
  261. public function scanCodePush($mp_id, $param) {
  262. $_open_id = get_val($param, 'FromUserName', '');
  263. if (empty($_open_id)) {
  264. die('');
  265. }
  266. }
  267. public function scanCodeWaitmsg($mp_id, $param) {
  268. $_open_id = get_val($param, 'FromUserName', '');
  269. if (empty($_open_id)) {
  270. die('');
  271. }
  272. }
  273. public function picSysPhoto($mp_id, $param) {
  274. $_open_id = get_val($param, 'FromUserName', '');
  275. if (empty($_open_id)) {
  276. die('');
  277. }
  278. }
  279. public function picPhotoOrAlbum($mp_id, $param) {
  280. $_open_id = get_val($param, 'FromUserName', '');
  281. if (empty($_open_id)) {
  282. die('');
  283. }
  284. }
  285. public function picWeixin($mp_id, $param) {
  286. $_open_id = get_val($param, 'FromUserName', '');
  287. if (empty($_open_id)) {
  288. die('');
  289. }
  290. }
  291. public function locationSelect($mp_id, $param) {
  292. $_open_id = get_val($param, 'FromUserName', '');
  293. if (empty($_open_id)) {
  294. die('');
  295. }
  296. }
  297. /**
  298. * 发送文本消息
  299. *
  300. * @param string $mp_id
  301. * @param string $open_id 玩家应用ID
  302. * @param string $text
  303. *
  304. * @return bool
  305. */
  306. public function sendTextMsg($mp_id, $open_id, $text = '') {
  307. $_msg_type = 'text';
  308. $_msg_data = [
  309. "content" => $text
  310. ];
  311. $_mp_conf = (new MpConfModel())->getDataByMpId($mp_id);
  312. if (empty($_mp_conf)) {
  313. Log::write(
  314. "func=".__FUNCTION__."&class=".__CLASS__
  315. ."&step=1&mp_id=$mp_id&open_id=".$open_id, Log::ERROR
  316. );
  317. return false;
  318. }
  319. $_wx_app_secret = $_mp_conf['app_secret'];
  320. (new OfficialAccountApi())->sendMsg($mp_id, $_wx_app_secret, $open_id, $_msg_type, $_msg_data);
  321. return true;
  322. }
  323. }