WeChatMenu.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. namespace app\common\utility;
  3. use app\common\library\WeChatObject;
  4. use app\main\service\WxResponseService;
  5. use think\Log;
  6. /**
  7. * 微信菜单管理
  8. * Class WeChatMenu
  9. * @package app\common\utility
  10. */
  11. class WeChatMenu{
  12. /**
  13. * 获取渠道微信菜单
  14. * @param $channel_id
  15. * @return mixed
  16. */
  17. static public function getChannelMenu($channel_id){
  18. $wx_menu = model('AdminConfig')->where('admin_id',$channel_id)->value('wx_menu');
  19. return $wx_menu;
  20. }
  21. /**
  22. * 获取系统默认菜单
  23. * @param $channel_id
  24. * @return mixed
  25. */
  26. static public function getSystemDefaultMenu($channel_id){
  27. $menu = json_decode(str_replace('cpsurl', '', config('site.wx_menu')), true);
  28. foreach($menu as $key => $val) {
  29. if (isset($val['url'])) {
  30. $menu[$key]['url'] = getCurrentDomain($channel_id, $val['url']);
  31. }
  32. if (isset($val['sub_button']) && !empty($val['sub_button'])) {
  33. foreach ($val['sub_button'] as $sub_k => $sub_v) {
  34. if (isset($sub_v['url'])) {
  35. $menu[$key]['sub_button'][$sub_k]['url'] = getCurrentDomain($channel_id, $sub_v['url']);
  36. }
  37. }
  38. }
  39. }
  40. return $menu;
  41. }
  42. static function replaceChannelMenuById($channel_id,$ophost_id, $is_qrcode_menu = '0'){
  43. $adminConfig = model('AdminConfig')->getAdminInfoAll($channel_id);
  44. $oldophost = '';
  45. //获取新域名信息
  46. $relace_host = model('Ophost')->where('id',$ophost_id)->column('platform_id,host');
  47. $ophost = current($relace_host);
  48. $platform_id = key($relace_host);
  49. if(empty($adminConfig['wx_menu'])){
  50. return [false,'替换渠道菜单失败,渠道菜单信息为空'];
  51. }
  52. //检查菜单是否为数组
  53. if(is_array($adminConfig['wx_menu'])){
  54. $adminConfig['wx_menu'] = json_encode($adminConfig['wx_menu'], JSON_UNESCAPED_UNICODE);
  55. }
  56. //查找以前菜单业务域名并替换
  57. if($adminConfig['menuophost_id']){
  58. $oldophost = model("ophost")->where("id", $adminConfig['menuophost_id'])->value("host");
  59. if (strpos($adminConfig['wx_menu'], $oldophost)){
  60. $adminConfig['wx_menu'] = str_replace($oldophost, $ophost, $adminConfig['wx_menu']);
  61. }
  62. }
  63. if ($is_qrcode_menu == '1') {
  64. // 使用二维码菜单 重新生成二维码
  65. WxResponseService::instance()->reStructWxMenu($channel_id, $oldophost, $ophost);
  66. }
  67. //查找以前的业务域名并替换
  68. if($adminConfig['ophost_id']){
  69. $oldophost = model("ophost")->where("id", $adminConfig['ophost_id'])->value("host");
  70. if (strpos($adminConfig['wx_menu'], $oldophost)){
  71. $adminConfig['wx_menu'] = str_replace($oldophost, $ophost, $adminConfig['wx_menu']);
  72. }
  73. }
  74. //转成数组
  75. if(!is_array($adminConfig['wx_menu'])){
  76. $adminConfig['wx_menu'] = json_decode($adminConfig['wx_menu'],true);
  77. }
  78. //推送菜单
  79. list($status,$message) = self::pushWeChatMenu($channel_id,$adminConfig['wx_menu']);
  80. Log::info(date('Y-m-d H:i:s')."Replace Channel WeChat Menu ChannelID:{$channel_id} PlatformID:{$platform_id} Source: {$oldophost} To: {$ophost} ISOK:".intval($status)." Message:".$message);
  81. //失败返回错误信息
  82. if(!$status){
  83. return [false,$message];
  84. }
  85. //成功返回菜单数组
  86. return [true,$adminConfig['wx_menu']];
  87. }
  88. /**
  89. * 检查菜单是否合法
  90. * @param $menu
  91. * @return bool
  92. */
  93. static public function checkWeChatMenu($menu){
  94. if(!$menu) return false;
  95. $hasError = false;
  96. /**
  97. * 校验menu数据格式
  98. */
  99. foreach ($menu as $k => $v) {
  100. if (isset($v['sub_button'])) {
  101. foreach ($v['sub_button'] as $m => $n) {
  102. if (isset($n['key']) && !$n['key']) {
  103. $hasError = false;
  104. break 2;
  105. }else{
  106. $hasError = true;
  107. continue;
  108. }
  109. }
  110. }else{
  111. if(isset($v['key']) && !$v['key']){
  112. $hasError = false;
  113. break;
  114. }else{
  115. $hasError = true;
  116. continue;
  117. }
  118. }
  119. }
  120. return $hasError;
  121. }
  122. /**
  123. * 推送菜单到微信
  124. * @param $channel_id
  125. * @param $menu
  126. * @param $platform_id
  127. * @return array
  128. * @throws \Exception
  129. */
  130. static public function pushWeChatMenu($channel_id,array $menu,$platform_id = null){
  131. try{
  132. $adminConfig = model('AdminConfig')->getAdminInfoAll($channel_id);
  133. $weChat = new WeChatObject($adminConfig);
  134. $officialAccount = $weChat->getOfficialAccount();
  135. if($platform_id){
  136. $officialAccount = $weChat->getOfficialAccountByPlatform($platform_id);
  137. }
  138. if(empty($menu)){
  139. throw new \Exception('菜单不能为空');
  140. }
  141. $officialAccount->menu->delete(); //删除全部菜单 主要是掌中云个性化菜单
  142. if ($adminConfig['is_qrcode_menu'] == '1') {
  143. // 菜单链接生成二维码图片
  144. $row = model('AdminWxmenu')->get(['admin_id' => $channel_id]);
  145. $menu = json_decode($row->wx_qrcode_menu, true);
  146. $ret = $officialAccount->menu->create($menu);
  147. } else {
  148. $ret = $officialAccount->menu->create($menu);
  149. if($ret && $ret['errcode'] == 0){
  150. $menu = self::rechargeMenuFilter($menu);
  151. if(!empty($menu)){
  152. $ret = $officialAccount->menu->create($menu,['client_platform_type' => 1]);
  153. }
  154. }else{
  155. throw new \Exception($ret['errmsg']);
  156. }
  157. }
  158. if($ret && isset($ret['errcode']) && $ret['errcode'] == 0){
  159. return [true,'ok'];
  160. }elseif($ret>0){
  161. return [true,'ok'];
  162. }else{
  163. throw new \Exception($ret['errmsg']);
  164. }
  165. }catch (\Exception $e){
  166. return [false,$e->getMessage()];
  167. }
  168. }
  169. /**
  170. * 过滤IOS系统的带有充值链接的微信菜单
  171. * @param $menu
  172. * @return mixed
  173. */
  174. static public function rechargeMenuFilter(&$menu){
  175. $rs = false;
  176. foreach($menu as $kk=>&$me){
  177. if(!isset($me['sub_button'])){
  178. if($me['type'] == 'view' && strpos($me['url'],'recharge')!==false){
  179. unset($menu[$kk]);
  180. }
  181. }else{
  182. if(count($me['sub_button']) == 1 && $me['sub_button'][0]['type'] == 'view' && strpos($me['sub_button'][0]['url'],'recharge')!==false){
  183. unset($menu[$kk]);
  184. }else{
  185. foreach($me['sub_button'] as $k=>&$m){
  186. if(isset($m['type']) && $m['type'] == 'view' && strpos($m['url'],'recharge')!==false){
  187. unset($menu[$kk]['sub_button'][$k]);
  188. }
  189. }
  190. $me['sub_button'] = array_values($me['sub_button']);
  191. }
  192. }
  193. }
  194. if(!empty($menu)){
  195. $menu = array_values($menu);
  196. $rs = self::checkWeChatMenu($menu);
  197. }
  198. if($rs){
  199. return $menu;
  200. }else{
  201. return [];
  202. }
  203. }
  204. }