MiniMessage.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. <?php
  2. /**
  3. * MiniMessage.php UTF-8
  4. * 小程序消息
  5. *
  6. * @date : 2018/9/14 20:52
  7. *
  8. * @license 这不是一个自由软件,未经授权不许任何使用和传播。
  9. * @author : wuyonghong <wyh@huosdk.com>
  10. * @version : HuoMp 1.0
  11. */
  12. namespace huoMpMsg\controller;
  13. use huo\controller\game\GameCache;
  14. use huo\controller\member\MemCache;
  15. use huo\controller\pay\SdkOrderCache;
  16. use huo\model\order\OrderModel;
  17. use huolib\constant\CacheConst;
  18. use huolib\constant\CommonConst;
  19. use huolib\constant\OauthConst;
  20. use huolib\constant\OrderConst;
  21. use huomp\logic\game\OaMpLogic;
  22. use huomp\model\weixin\MpConfModel;
  23. use huomp\model\weixin\OaMpModel;
  24. use huoMpMsg\constant\OfficialAccountConst;
  25. use huoMpMsg\model\MpMsgLogModel;
  26. use huoMpMsg\status\OfficialAccountStatus;
  27. use think\Cache;
  28. use think\Log;
  29. class MiniMessage {
  30. /**
  31. * 接收微信数据
  32. *
  33. * @param string $mp_id 小程序ID
  34. * @param array $param
  35. *
  36. * @return bool
  37. */
  38. public function receive($mp_id, $param) {
  39. if (isset($param['MsgType']) && 'event' == $param['MsgType'] && 'user_enter_tempsession' == $param['Event']) {
  40. /* 直接进来客服 查询是否有订单需要支付 获取缓存信息 */
  41. $this->sendOrderEnter($mp_id, $param['FromUserName']);
  42. return true;
  43. } else if (isset($param['MsgType']) && 'text' == $param['MsgType']
  44. && false !== strpos(
  45. $param['Content'], OfficialAccountConst::MSG_RECEIVE_TEXT_1
  46. )) {
  47. /* 回复1 获取二维码 */
  48. $this->sendOaQrCode($mp_id, $param['FromUserName']);
  49. } else if (isset($param['MsgType']) && 'text' == $param['MsgType']
  50. && false !== strpos(
  51. $param['Content'], OfficialAccountConst::MSG_RECEIVE_TEXT_2
  52. )) {
  53. /* 回复2 获取最近一笔订单,已支付提示已支付,未支付弹出支付链接*/
  54. $this->sendOrder($mp_id, $param['FromUserName']);
  55. } else {
  56. $_p_content = isset($param['Content']) ? $param['Content'] : '';
  57. $_msg = (new OaReturnMsg())->getKeyReturnMsg($mp_id, $_p_content);
  58. if (!empty($_msg)) {
  59. (new OaMessage())->sendTextMsg($mp_id, $param['FromUserName'], $_msg);
  60. }
  61. }
  62. $_data['mp_id'] = $mp_id;
  63. $_data['wx_msg_id'] = get_val($param, 'MsgId', 0);
  64. $_data['source_id'] = get_val($param, 'ToUserName', '');
  65. $_data['open_id'] = get_val($param, 'FromUserName', '');
  66. $_data['msg_type'] = get_val($param, 'MsgType', '');
  67. $_data['pic_url'] = get_val($param, 'PicUrl', '');
  68. $_data['media_id'] = get_val($param, 'MediaId', '');
  69. $_data['title'] = get_val($param, 'Title', '');
  70. $_data['mini_app_id'] = get_val($param, 'AppId', '');
  71. $_data['page_path'] = get_val($param, 'PagePath', '');
  72. $_data['thumb_url'] = get_val($param, 'ThumbUrl', '');
  73. $_data['thumb_media_id'] = get_val($param, 'ThumbMediaId', '');
  74. $_data['text'] = get_val($param, 'Content', '');
  75. $_data['wx_create_time'] = get_val($param, 'CreateTime', 0);
  76. $_model = new MpMsgLogModel();
  77. $_rs = $_model->hasMsg($_data['wx_msg_id']);
  78. if (empty($_rs)) {
  79. $_model->insertLog($_data);
  80. }
  81. return true;
  82. }
  83. /**
  84. * 小游戏客服充值进入客服触发调用
  85. *
  86. * @param string $mp_id
  87. * @param string $open_id
  88. *
  89. * @return bool
  90. */
  91. public function sendOrderEnter($mp_id, $open_id) {
  92. $_mem_id = MemCache::ins()->getMemIdByOpenId(OauthConst::OAUTH_MP, $open_id);
  93. if (empty($_mem_id)) {
  94. Log::write(
  95. "func=".__FUNCTION__."&class=".__CLASS__
  96. ."&step=1&mp_id=$mp_id&open_id=$open_id&mem_id=$_mem_id&err_msg=玩家ID不存在",
  97. Log::ERROR
  98. );
  99. return false;
  100. }
  101. $_order_id = Cache::get(CacheConst::CACHE_CUSTOMER_ORDER_PAY_PREFIX.$_mem_id);
  102. /* 不存在最近订单 不做任何处理 */
  103. if (empty($_order_id)) {
  104. return true;
  105. }
  106. return $this->sendOrderData($mp_id, $open_id, $_order_id);
  107. }
  108. /**
  109. * 小游戏客服充值
  110. *
  111. * @param string $mp_id
  112. * @param string $open_id
  113. *
  114. * @return bool
  115. */
  116. public function sendOrder($mp_id, $open_id) {
  117. $_mem_id = MemCache::ins()->getMemIdByOpenId(OauthConst::OAUTH_MP, $open_id);
  118. if (empty($_mem_id)) {
  119. Log::write(
  120. "func=".__FUNCTION__."&class=".__CLASS__
  121. ."&step=1&mp_id=$mp_id&open_id=$open_id&mem_id=$_mem_id&err_msg=玩家ID不存在",
  122. Log::ERROR
  123. );
  124. return false;
  125. }
  126. $_order_id = Cache::get(CacheConst::CACHE_CUSTOMER_ORDER_PAY_PREFIX.$_mem_id);
  127. /* 不存在最近订单,获取最后一个订单,若订单未支付弹出订单,已支付则不做任何处理 */
  128. if (empty($_order_id)) {
  129. $_order_id = (new OrderModel())->getMemLastOrderId($_mem_id);
  130. if (empty($_order_id)) {
  131. return false;
  132. }
  133. }
  134. return $this->sendOrderData($mp_id, $open_id, $_order_id);
  135. }
  136. /**
  137. * 发送订单信息
  138. *
  139. * @param $mp_id
  140. * @param $open_id
  141. * @param $order_id
  142. *
  143. * @return bool
  144. */
  145. public function sendOrderData($mp_id, $open_id, $order_id) {
  146. $_order_data = SdkOrderCache::ins()->getInfoByOrderId($order_id);
  147. if (empty($_order_data)) {
  148. Log::write(
  149. "func=".__FUNCTION__."&class=".__CLASS__
  150. ."&step=1&mp_id=$mp_id&open_id=$open_id&order_id=$order_id&err_msg=订单不存在",
  151. Log::ERROR
  152. );
  153. return false;
  154. }
  155. if (OrderConst::PAY_STATUS_SUC == $_order_data['status']) {
  156. /* 已支付的不做任何处理 */
  157. return true;
  158. }
  159. /* 获取小程序默认关联公众号 */
  160. $_wx_app_id = (new OaMpLogic())->getDefaultOaId($_order_data['app_id']);
  161. $_game_data = GameCache::ins()->getInfoByAppId($_order_data['app_id']);
  162. $_data = [
  163. "title" => '点我充值',
  164. "description" => '点我充值'.$_order_data['real_amount'].'元',
  165. "url" => MPBOXSITE.'/order/index?wx_app_id='.$_wx_app_id.'&order_id='.$order_id,
  166. "thumb_url" => cmf_get_image_url($_game_data['icon'])
  167. ];
  168. return $this->sendLinkMsg($mp_id, $open_id, $_data);
  169. }
  170. /**
  171. * 发送图文消息
  172. *
  173. * @param string $mp_id
  174. * @param string $open_id 玩家应用ID
  175. * @param string $data
  176. *
  177. * @return bool
  178. */
  179. public function sendLinkMsg($mp_id, $open_id, $data = '') {
  180. $_msg_type = OfficialAccountConst::MSG_TYPE_LINK;
  181. if (empty($data)) {
  182. Log::write(
  183. "func=".__FUNCTION__."&class=".__CLASS__
  184. ."&step=1&mp_id=$mp_id&open_id=$open_id&err_msg=发送数据为空", Log::ERROR
  185. );
  186. return false;
  187. }
  188. $_mp_conf = (new MpConfModel())->getDataByMpId($mp_id);
  189. if (empty($_mp_conf)) {
  190. Log::write(
  191. "func=".__FUNCTION__."&class=".__CLASS__
  192. ."&step=2&mp_id=$mp_id&open_id=".$open_id, Log::ERROR
  193. );
  194. return false;
  195. }
  196. $_wx_app_secret = $_mp_conf['app_secret'];
  197. (new OfficialAccountApi())->sendMsg($mp_id, $_wx_app_secret, $open_id, $_msg_type, $data);
  198. return true;
  199. }
  200. /**
  201. * 发送公众号二维码
  202. *
  203. * @param string $mp_id
  204. * @param string $open_id
  205. *
  206. * @return bool
  207. */
  208. public function sendOaQrCode($mp_id, $open_id) {
  209. $_media_id = $this->getQrCodeMediaId($mp_id);
  210. $_msg_type = 'image';
  211. $_data = [
  212. "media_id" => $_media_id
  213. ];
  214. $_mp_conf = (new MpConfModel())->getDataByMpId($mp_id);
  215. if (empty($_mp_conf) || empty($_media_id)) {
  216. Log::write("func=".__FUNCTION__."&class=".__CLASS__."&step=1&mp_id=$mp_id&open_id=$open_id", Log::ERROR);
  217. return false;
  218. }
  219. $_wx_app_secret = $_mp_conf['app_secret'];
  220. $_rs = (new OfficialAccountApi())->sendMsg($mp_id, $_wx_app_secret, $open_id, $_msg_type, $_data);
  221. if (OfficialAccountStatus::WX_SYSTEM_ERROR == $_rs['code']) {
  222. unset($_rs);
  223. unset($_data);
  224. $_media_id = $this->getQrCodeMediaId($mp_id, true);
  225. $_data = [
  226. "media_id" => $_media_id
  227. ];
  228. $_rs = (new OfficialAccountApi())->sendMsg($mp_id, $_wx_app_secret, $open_id, $_msg_type, $_data);
  229. }
  230. if (OfficialAccountStatus::NO_ERROR != $_rs['code']) {
  231. return false;
  232. }
  233. return true;
  234. }
  235. /**
  236. * 获取二维码的媒体ID
  237. *
  238. * @param string $mp_id 公众号ID
  239. *
  240. * @param bool $check_get 是否校验media_id 有效性
  241. *
  242. * @return bool|mixed
  243. */
  244. public function getQrCodeMediaId($mp_id, $check_get = false) {
  245. $_cache_key = CacheConst::CACHE_MP_QRCODE_PREFIX.$mp_id;
  246. $_data = Cache::get($_cache_key);
  247. if (!empty($_data) && false == $check_get) {
  248. return $_data;
  249. }
  250. $_mp_model = new MpConfModel();
  251. $_app_id = $_mp_model->getAppIdByMpId($mp_id);
  252. $_game_info = GameCache::ins()->getInfoByAppId($_app_id);
  253. $_qr_code = !empty($_game_info['ext_info']['auto_help']) ? $_game_info['ext_info']['auto_help'] : '';
  254. if (empty($_qr_code)) {
  255. $_oa_id = (new OaMpModel())->getOaByApp($_app_id);
  256. $_oa_data = $_mp_model->getDataByMpId($_oa_id);
  257. $_qr_code = !empty($_oa_data) ? $_oa_data['qr_code'] : '';
  258. }
  259. $_mp_conf = $_mp_model->getDataByMpId($mp_id);
  260. if (empty($_mp_conf)) {
  261. Log::write("func=".__FUNCTION__."&class=".__CLASS__."&step=1&mp_id=$mp_id", Log::ERROR);
  262. return false;
  263. }
  264. $_file_path = CMF_ROOT.'/public/upload/'.$_qr_code;
  265. if (empty($_qr_code)) {
  266. $_file_path = '/mini/public/upload/qrcode_for_gh_a30f9cefe8e9_258.jpg';
  267. }
  268. if (true != file_exists($_file_path)) {
  269. Log::write(
  270. "func=".__FUNCTION__."&class=".__CLASS__."&step=2&mp_id=$mp_id&qr_code=$_qr_code&file_path="
  271. .$_file_path, Log::ERROR
  272. );
  273. return false;
  274. }
  275. $_wx_app_secret = $_mp_conf['app_secret'];
  276. $_rs = (new OfficialAccountApi())->imageUpload($mp_id, $_wx_app_secret, $_file_path);
  277. if (OfficialAccountStatus::NO_ERROR != $_rs['code'] || empty($_rs['data']['media_id'])) {
  278. Log::write(
  279. "func=".__FUNCTION__."&class=".__CLASS__."&step=3&mp_id=$mp_id&file_path=".$_file_path."&rs="
  280. .json_encode($_rs), Log::ERROR
  281. );
  282. return false;
  283. }
  284. Cache::set($_cache_key, $_rs['data']['media_id'], CommonConst::CONST_DAY_SECONDS * 3);
  285. return $_rs['data']['media_id'];
  286. }
  287. }