Officialaccount.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. <?php
  2. namespace app\wechat\controller;
  3. use EasyWeChat\Kernel\Messages\News;
  4. use EasyWeChat\Kernel\Messages\NewsItem;
  5. use EasyWeChat\Kernel\Messages\Image;
  6. use EasyWeChat\Kernel\Messages\Text;
  7. use think\Request;
  8. use app\wechat\controller\Gzhconfig;
  9. use think\facade\Db;
  10. use think\facade\Session;
  11. use EasyWeChat\OfficialAccount\Application;
  12. use think\App;
  13. class Officialaccount{
  14. private $url;
  15. public function __construct(){
  16. $this->url = 'https://www.yiguanfep.com/';
  17. self::checkSignature();
  18. $this->subscribe_content = '感谢您关注逸管FEP公众号!
  19. 您可以通过下方菜单栏轻松进入逸管系统的移动端页面。若您需要使用电脑操作,欢迎访问我们的系统网站:www.yiguanfep.com,以登录至PC端系统。
  20. 如果您在使用过程中需要任何技术支持或客服咨询,请随时扫描我们提供的企业微信客服二维码。我们的专业团队将在工作日的8:30至18:00之间为您提供详尽的解答与协助。
  21. 再次感谢您的关注,期待为您服务!';
  22. }
  23. private function checkSignature(){
  24. if(!empty($_GET['echostr'])){
  25. // self::checkSignature();
  26. $signature = $_GET["signature"];
  27. $timestamp = $_GET["timestamp"];
  28. $nonce = $_GET["nonce"];
  29. $echostr = $_GET["echostr"];
  30. $wechat = new Gzhconfig();
  31. $app = $wechat->app;
  32. $token = $app->config->token;
  33. $tmpArr = array($token, $timestamp, $nonce);
  34. sort($tmpArr, SORT_STRING);
  35. $tmpStr = implode( $tmpArr );
  36. $tmpStr = sha1( $tmpStr );
  37. if( $tmpStr == $signature ){
  38. // header('Content-Type: text/html; charset=utf-8');
  39. echo $echostr;
  40. exit;
  41. }else{
  42. return 'Token verification failed.';
  43. }
  44. }
  45. }
  46. // 生成二维码
  47. public function creatQrCode($uid){
  48. $wechat = new Gzhconfig();
  49. $app = $wechat->app;
  50. $result = $app->qrcode->temporary($uid, 1 * 5 * 60); // 二维码有效时间为5分钟
  51. $url = $app->qrcode->url($result['ticket']);
  52. return $url;
  53. }
  54. // 获取二维码
  55. public function getQrCode(){
  56. $uid = make_token();
  57. // $uid = 'y123456789';
  58. $url = self::creatQrCode($uid);
  59. $data = [
  60. 'uid' => $uid,
  61. 'url' => $url,
  62. ];
  63. // return $url;
  64. return view('login', $data);
  65. }
  66. // 获取二维码 用于用户扫码绑定
  67. public function getQrCode_bindAccount(){
  68. // $uid = make_token();
  69. $uid = self::get_login_admin('username');
  70. $url = self::creatQrCode($uid);
  71. $data = [
  72. 'uid' => $uid,
  73. 'url' => $url,
  74. ];
  75. return $data['url'];
  76. // return view('login', $data);
  77. }
  78. // 消息事件
  79. public function index(){
  80. // self::checkSignature();
  81. $wechat = new Gzhconfig();
  82. $app = $wechat->app;
  83. $app->server->push(function ($message) {
  84. switch ($message['MsgType']) {
  85. case 'event':
  86. // return '收到事件消息';
  87. // return $message;
  88. return self::evenMessage($message);
  89. break;
  90. // case 'text':
  91. // return "收到文字消息";
  92. // break;
  93. // case 'image':
  94. // return '收到图片消息';
  95. // break;
  96. // case 'voice':
  97. // return '收到语音消息';
  98. // break;
  99. // case 'video':
  100. // return '收到视频消息';
  101. // break;
  102. // case 'location':
  103. // return '收到坐标消息';
  104. // break;
  105. // case 'link':
  106. // return '收到链接消息';
  107. // break;
  108. // case 'file':
  109. // return '收到文件消息';
  110. // ... 其它消息
  111. default:
  112. return self::send_service_QRcode();
  113. // return '收到其它消息';
  114. break;
  115. }
  116. // ...
  117. });
  118. $response = $app->server->serve();
  119. $response->send();
  120. }
  121. // 消息接入
  122. public function evenMessage($message){
  123. switch($message['Event']){
  124. case 'subscribe':
  125. if(!empty($message['EventKey'])){
  126. $message['EventKey'] = substr($message['EventKey'], 8);
  127. // $res = self::loginEvent($message);
  128. }
  129. $res = Db::name('admin')->where('username', $message['EventKey'])->find();
  130. if($res != NULL){
  131. return $this->subscribe_content.self::scanBind($message);
  132. }else{
  133. return $this->subscribe_content;
  134. }
  135. break;
  136. case 'SCAN':
  137. return self::scanBind($message);
  138. case 'unsubscribe':
  139. return '取消关注!!!';
  140. break;
  141. case 'CLICK':
  142. return self::clickEvent($message);
  143. break;
  144. default:
  145. return '其他事件';
  146. break;
  147. }
  148. }
  149. // 扫码绑定微信公众号
  150. public function scanBind($message){
  151. $wechat = new Gzhconfig();
  152. $app = $wechat->app;
  153. $openid = $message['FromUserName'];
  154. $user = $app->user->get($openid); // 用户信息
  155. $admin_username = $message['EventKey'];
  156. $data = [
  157. 'subscribe_wx' => $user['subscribe'],
  158. 'subscribe_time' => $user['subscribe_time'],
  159. 'wx_nickname' => $user['nickname'],
  160. 'openid' => $user['openid'],
  161. ];
  162. // 判断该账号是否已经存在微信用户绑定
  163. $is_wechat_uid = Db::name('Admin')->where('username', $admin_username)->field('username,openid')->find();
  164. // 该扫码微信用户之前是否绑定了其他账号
  165. $old_wechat = Db::name('Admin')->where('openid', $data['openid'])->value('username');
  166. // return json_encode($old_wechat);
  167. Db::name('admin')->where('username', $admin_username)->update($data);
  168. if($is_wechat_uid['openid'] != NULL && $is_wechat_uid['username'] != $old_wechat){ // 存在微信用户绑定了该系统账号
  169. // sendText($uid, "您系统账号已被其他微信用户绑定,请及时重新绑定!");
  170. $app->broadcasting->previewText("您系统账号已被其他微信用户绑定,请及时确认账号是否泄露,并修改密码!", $is_wechat_uid['openid']);
  171. }
  172. if($old_wechat != NULL && $is_wechat_uid['username'] != $old_wechat){
  173. Db::name('admin')->where('username', $old_wechat)->update(['openid' => '']);
  174. return '已解除之前绑定的账号:'.$old_wechat.'!'.'绑定账号:'.$admin_username.',成功!!!';
  175. }
  176. if($is_wechat_uid['username'] == $old_wechat){
  177. return '当前已绑定账号:'.$admin_username;
  178. }
  179. return '绑定账号:'.$admin_username.',成功!!!';
  180. }
  181. // 点击事件
  182. public function clickEvent($message){
  183. $wechat = new Gzhconfig();
  184. $app = $wechat->app;
  185. $openid = $message['FromUserName'];
  186. $eventKey = $message['EventKey'];
  187. if($eventKey === '客服二维码图'){
  188. // return self::bindAccount($message);
  189. return self::send_service_QRcode($message);
  190. }
  191. // $user = $app->user->get($openid);
  192. // $user = json_encode($message);
  193. // // $image = new Image('serviceQRcode.jpg');
  194. $accessToken = $app->access_token;
  195. $token = $accessToken->getToken();
  196. // $token = json_encode($token);
  197. $token = $token['access_token'];
  198. return $token;
  199. // return "!!!";
  200. }
  201. // 发送 文本 信息给用户
  202. public function sendText($uid, $content){
  203. $where = array();
  204. for($i = 0; $i < count((array)$uid); $i++){
  205. $where[$i] = ['id', '=', $uid[$i]];
  206. }
  207. // dump($where);
  208. $list = Db::name('admin')->whereOr($where)->field('openid')->select();
  209. $openid = array();
  210. for($i = 0; $i < count($list); $i++){
  211. $openid[$i] = $list[$i]['openid'];
  212. }
  213. $wechat = new Gzhconfig();
  214. $app = $wechat->app;
  215. // $content = "你好!!";
  216. for($i = 0; $i < count($openid); $i++){
  217. if(empty($openid[$i])){
  218. continue;
  219. }
  220. $app->broadcasting->previewText($content, $openid[$i]);
  221. }
  222. }
  223. // 随便发条消息
  224. public function send_text($openid,$content){
  225. $wechat = new Gzhconfig();
  226. $app = $wechat->app;
  227. $app->broadcasting->previewText($content, $openid);
  228. }
  229. // 推送客服二维码Push customer service QR code
  230. public function send_service_QRcode(){
  231. // $image = new Image('7lZmgSWM2jYgNk6O0_v6o1MopKqJvnqLhV_n6oA_r-v9b-yahEo0g9K4p7QK5zd-');
  232. $image = new Image('sKn3bXRusq_4bu1QHfEO3pLRn4ndyB-W637Qnv0f55ZURrIZDhirc0sgjVvZvOQC');
  233. return $image;
  234. }
  235. // 回复 图文 信息给用户
  236. public function bindAccount($message){
  237. $wechat = new Gzhconfig();
  238. $app = $wechat->app;
  239. $items = [
  240. new NewsItem([
  241. 'title' => '绑定账号',
  242. 'description' => '...',
  243. 'url' => 'www.baidu.com',
  244. 'image' => '',
  245. ]),
  246. ];
  247. $news = new News($items);
  248. return $news;
  249. }
  250. // 创建菜单
  251. public function menu(){
  252. $wechat = new Gzhconfig();
  253. $app = $wechat->app;
  254. $buttons = [
  255. [
  256. "name" => "系统功能",
  257. "sub_button" => [
  258. [
  259. "type" => "view",
  260. "name" => "登录入口",
  261. // "url" => "https://open.weixin.qq.com//mobile/index/main",
  262. "url" => $this->url."mobile/Login/Login",
  263. ],
  264. [
  265. "type" => "view",
  266. "name" => "项目跟踪",
  267. // "url" => "https://open.weixin.qq.com//mobile/index/main",
  268. "url" => $this->url."mobile/temporary/kan_list",
  269. ],
  270. ],
  271. ],
  272. [
  273. "name" => "客服咨询",
  274. "sub_button" => [
  275. [
  276. "type" => "click",
  277. "name" => "客服二维码",
  278. "key" => "客服二维码图",
  279. ],
  280. ],
  281. ],
  282. ];
  283. $app->menu->create($buttons);
  284. // dump($app->menu->create($buttons));
  285. }
  286. // 网页授权
  287. public function OAuth(){
  288. $wechat = new Gzhconfig();
  289. $app = $wechat->app;
  290. session::clear();
  291. // $response = $app->oauth->scopes(['snsapi_userinfo'])->redirect($app->config->OAuth_redirect_uri)->send();
  292. $response = $app->oauth->redirect();
  293. // halt($response);
  294. redirect($response)->send();
  295. // header("Location: {$response}");
  296. // dump($response);
  297. exit;
  298. }
  299. // 网页授权回调接口
  300. public function OAuthUser(){
  301. $code = input('code', '');
  302. $wechat = new Gzhconfig();
  303. $app = $wechat->app;
  304. // echo json_encode($app->oauth->user()->toArray(), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);
  305. $user = $app->oauth->userFromCode($code);
  306. // dump($user);
  307. $user_data = [
  308. 'openid' => $user->getId(),
  309. 'name' => $user->getName(),
  310. 'avater' => $user->getAvatar(),
  311. ];
  312. $admin = Db::name('Admin')->where(['openid' => $user_data['openid']])->find();
  313. if($admin == NULL){
  314. echo '<div style="text-align:center;color:red;margin-top:20%;">您未绑定系统账号,请先登录系统扫码绑定账号!</div>';
  315. exit;
  316. }
  317. // dump($admin);
  318. $data = [
  319. 'last_login_time' => time(),
  320. 'last_login_ip' => request()->ip(),
  321. 'login_num' => $admin['login_num'] + 1,
  322. ];
  323. Db::name('admin')->where(['id' => $admin['id']])->update($data);
  324. $session_admin = get_config('app.session_admin');
  325. Session::set($session_admin, $admin);
  326. $token = make_token();
  327. set_cache($token, $admin, 7200);
  328. $admin['token'] = $token;
  329. // halt($session_admin);
  330. $response = $this->url."mobile/index/main?admin=".$admin['id'];
  331. // redirect($this->url."mobile/index/main")->send();
  332. // halt($response);
  333. redirect($response)->send();
  334. // header("Location: {$response}");
  335. // exit;
  336. }
  337. public function OAuthUserGetOpenId(){
  338. $code = input('code', '');
  339. $wechat = new Gzhconfig();
  340. $app = $wechat->app;
  341. $user = $app->oauth->userFromCode($code);
  342. return Json($user = $app->user->get($user->getId()));
  343. }
  344. public function getUserInfo($accessToken, $openid) {
  345. $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$accessToken}&openid={$openid}&lang=zh_CN";
  346. // 初始化cURL会话
  347. $ch = curl_init();
  348. // 设置cURL选项
  349. curl_setopt($ch, CURLOPT_URL, $url);
  350. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  351. curl_setopt($ch, CURLOPT_TIMEOUT, 30);
  352. // 执行cURL请求
  353. $response = curl_exec($ch);
  354. // 检查是否有错误发生
  355. if (curl_errno($ch)) {
  356. $error_msg = curl_error($ch);
  357. curl_close($ch);
  358. $this->ajaxReturn(['status' => 'error', 'message' => 'CURL Error: ' . $error_msg]);
  359. return;
  360. }
  361. // 关闭cURL会话
  362. curl_close($ch);
  363. $userData = json_decode($response, true);
  364. return $userData;
  365. }
  366. // 获取登录账号的信息
  367. public function get_login_admin($key = "")
  368. {
  369. $session_admin = get_config('app.session_admin');
  370. if (\think\facade\Session::has($session_admin)) {
  371. $gougu_admin = \think\facade\Session::get($session_admin);
  372. if (!empty($key)) {
  373. if (isset($gougu_admin[$key])) {
  374. return $gougu_admin[$key];
  375. } else {
  376. return '';
  377. }
  378. } else {
  379. return $gougu_admin;
  380. }
  381. } else {
  382. return '';
  383. }
  384. }
  385. public function login()
  386. {
  387. // 创建 EasyWeChat 实例
  388. $this->config = [
  389. 'app_id' => 'wx52b56e5d84b68877',
  390. 'secret' => '4e673d40629698a52aed41339f1c2ab4',
  391. 'token' => 'ydmheyiguanhezuo',
  392. 'aes_key' => 'LntRHYrfBjQ43tYhlTev09wUPu06w03yeCb8Bl7Ibjq',
  393. 'response_type' => 'array',
  394. ];
  395. $wechat = new Gzhconfig();
  396. $app = $wechat->app;
  397. // 生成授权 URL
  398. $redirectUrl = $app->oauth->redirect()->getTargetUrl();
  399. // 跳转到微信授权页面
  400. return redirect($redirectUrl);
  401. }
  402. public function callback()
  403. {
  404. // 创建 EasyWeChat 实例
  405. $config = [
  406. 'app_id' => 'YourAppID',
  407. 'secret' => 'YourAppSecret',
  408. ];
  409. $app = Factory::officialAccount($config);
  410. // 获取用户信息
  411. $user = $app->oauth->user();
  412. // 处理用户信息,例如保存到数据库,获取用户的 OpenID 和其他信息
  413. // $openid = $user->getId();
  414. // $nickname = $user->getNickname();
  415. // 这里可以根据需求进行处理
  416. return '微信登录成功!'; // 可以返回一个视图或其他响应
  417. }
  418. // {
  419. // "ToUserName":"gh_6c83d45c1d53",
  420. // "FromUserName":"oCfTc6Vk-3yw6Qn1Ejazz2EM36ls", //openid 28位
  421. // "CreateTime":"1697787353",
  422. // "MsgType":"event", // 消息类型
  423. // "Event":"SCAN", // 事件类型
  424. // "EventKey":"6bb300bfe3aff3f7dbe1947ffdd1bbd669425122", //uid
  425. // "Ticket":"gQEC8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyd1pKSE5qOVFmc0YxMDJMT3hCY1EAAgTWLTJlAwQsAQAA"
  426. // }
  427. // {
  428. // "ToUserName":"gh_6c83d45c1d53",
  429. // "FromUserName":"oCfTc6TlaahmhT4LsOcurzkfFx7Q", //openid 28位
  430. // "CreateTime":"1697787655",
  431. // "MsgType":"event",
  432. // "Event":"SCAN",
  433. // "EventKey":"065e139d7ee6c5f53e61954bad5e3452fac28de9",
  434. // "Ticket":"gQEe8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyR21HLU5HOVFmc0YxMHRNT2hCY0QAAgTxLjJlAwQsAQAA"
  435. // }
  436. // 微信用户信息 颜
  437. // {
  438. // "subscribe":1,
  439. // "openid":"oCfTc6Vk-3yw6Qn1Ejazz2EM36ls",
  440. // "nickname":"",
  441. // "sex":0,
  442. // "language":"zh_CN",
  443. // "city":"",
  444. // "province":"",
  445. // "country":"",
  446. // "headimgurl":"",
  447. // "subscribe_time":1697789934,
  448. // "remark":"",
  449. // "groupid":0,
  450. // "tagid_list":[],
  451. // "subscribe_scene":"ADD_SCENE_QR_CODE",
  452. // "qr_scene":0,
  453. // "qr_scene_str":"b4082657616ddac77d9a2c92c6ca2a504e250595"
  454. // }
  455. }