Index.php 12.7 KB
<?php

namespace addons\wechat\controller;

use addons\wechat\library\Config;
use addons\wechat\model\WechatAutoreply;
use addons\wechat\model\WechatCaptcha;
use addons\wechat\model\WechatContext;
use addons\wechat\model\WechatResponse;
use addons\wechat\model\WechatConfig;

use app\common\library\Menu;
use EasyWeChat\Factory;
use addons\wechat\library\Wechat as WechatService;
use addons\wechat\library\Config as ConfigService;
use think\Log;
use think\Db;
use fast\Date;
use fast\Random;
use fast\Http;
use addons\third\model\Third;
use think\Session;

/**
 * 微信接口
 */
class Index extends \think\addons\Controller
{

    public $app = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->app = Factory::officialAccount(Config::load());
    }

    /**
     *
     */
    public function index()
    {

        $menu = [
            [
                'name'    => 'wechat',
                'title'   => '微信管理',
                'icon'    => 'fa fa-wechat',
                'sublist' => [
                    [
                        'name'    => 'wechat/autoreply',
                        'title'   => '自动回复管理',
                        'icon'    => 'fa fa-reply-all',
                        'sublist' => [
                            ['name' => 'wechat/autoreply/index', 'title' => '查看'],
                            ['name' => 'wechat/autoreply/add', 'title' => '添加'],
                            ['name' => 'wechat/autoreply/edit', 'title' => '修改'],
                            ['name' => 'wechat/autoreply/del', 'title' => '删除'],
                            ['name' => 'wechat/autoreply/multi', 'title' => '批量更新'],
                        ]
                    ],
                    [
                        'name'    => 'wechat/config',
                        'title'   => '配置管理',
                        'icon'    => 'fa fa-cog',
                        'sublist' => [
                            ['name' => 'wechat/config/index', 'title' => '查看'],
                            ['name' => 'wechat/config/add', 'title' => '添加'],
                            ['name' => 'wechat/config/edit', 'title' => '修改'],
                            ['name' => 'wechat/config/del', 'title' => '删除'],
                            ['name' => 'wechat/config/multi', 'title' => '批量更新'],
                        ]
                    ],
                    [
                        'name'    => 'wechat/menu',
                        'title'   => '菜单管理',
                        'icon'    => 'fa fa-list',
                        'sublist' => [
                            ['name' => 'wechat/menu/index', 'title' => '查看'],
                            ['name' => 'wechat/menu/add', 'title' => '添加'],
                            ['name' => 'wechat/menu/edit', 'title' => '修改'],
                            ['name' => 'wechat/menu/del', 'title' => '删除'],
                            ['name' => 'wechat/menu/remote', 'title' => '加载远程菜单'],
                            ['name' => 'wechat/menu/sync', 'title' => '同步'],
                            ['name' => 'wechat/menu/multi', 'title' => '批量更新'],
                        ]
                    ],
                    [
                        'name'    => 'wechat/response',
                        'title'   => '资源管理',
                        'icon'    => 'fa fa-list-alt',
                        'sublist' => [
                            ['name' => 'wechat/response/index', 'title' => '查看'],
                            ['name' => 'wechat/response/add', 'title' => '添加'],
                            ['name' => 'wechat/response/edit', 'title' => '修改'],
                            ['name' => 'wechat/response/del', 'title' => '删除'],
                            ['name' => 'wechat/response/select', 'title' => '选择'],
                            ['name' => 'wechat/response/multi', 'title' => '批量更新'],
                        ]
                    ]
                ]
            ]
        ];
        Menu::create($menu);
        return true;
    }

    /**
     * 微信API对接接口
     */
    public function api()
    {
        $this->app->server->push(function ($message) {
            $wechatService = new WechatService;

            $matches = null;
            $openid = $message['FromUserName'];
            $to_openid = $message['ToUserName'];
            //file_put_contents("pcl_wct.log", date("Y-m-d H:i:s") . "1-::" . json_encode($message, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);

            $unknownMessage = WechatConfig::getValue('default.unknown.message');
            $unknownMessage = $unknownMessage ? $unknownMessage : "";

            switch ($message['MsgType']) {
                case 'event': //事件消息
                    $event = $message['Event'];
                    $eventkey = $message['EventKey'] ? $message['EventKey'] : $message['Event'];
                    //验证码消息
                    if (in_array($event, ['subscribe', 'SCAN']) && preg_match("/^captcha_([a-zA-Z0-9]+)_([0-9\.]+)/", $eventkey, $matches)) {
                        return WechatCaptcha::send($openid, $matches[1], $matches[2]);
                    }
                    switch ($event) {
                        case 'subscribe'://添加关注
                            $subscribeMessage = WechatConfig::getValue('default.subscribe.message');
                            //$subscribeMessage = $subscribeMessage ? $subscribeMessage : "欢迎关注惠蒙房地产交易综合服务大厅!";
                            $subscribeMessage = '欢迎关注万顺元网约车';
                            //$subscribeMessage = '欢迎关注蒙自市房地产交易综合服务大厅,<a data-miniprogram-appid="wx0a5edd82c146e6f4" data-miniprogram-path="pages/home/mine1/mine1" href="https://fdc.xp.yn.cn" data-miniprogram-type="text">点击链接注册成为物业经理</a>';
                            //获得access_token
                            $getAccessToken = $this->getAccessToken();
                            //获得用户信息
                            $params = [];
                            $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $getAccessToken . "&openid=" . $openid . "&lang=zh_CN";
                            $userInfo = Http::sendRequest($url, $params, 'GET');
                            //根据UnionID判断用户是否已注册

                            $u_info_data = json_decode($userInfo['msg'], true);

                            $ucks = Db::name('wct_user')
                                ->where(['unionid' => $u_info_data['unionid']])
                                ->find();

                            if (empty($ucks)) {
                                $useradd['unionid'] = $u_info_data['unionid'];
                                $useradd['wx_openid'] = $openid;
                                $useradd['loginip'] = request()->ip();
                                $useradd['createtime'] = time();
                                Db::name('wct_user')->insertGetId($useradd);
                            }

                            //file_put_contents("pcl_wct.log", date("Y-m-d H:i:s") . "::3-" . json_encode($userInfo['msg'], JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                            return $subscribeMessage;

                        case 'unsubscribe'://取消关注
                            return '';
                        case 'LOCATION'://获取地理位置
                            return '';
                        case 'VIEW': //跳转链接,eventkey为链接
                            return '';
                        case 'SCAN': //扫码
                            return '';
                        default:
                            break;
                    }

                    $wechatResponse = WechatResponse::where(["eventkey" => $eventkey, 'status' => 'normal'])->find();
                    if ($wechatResponse) {
                        $responseContent = (array)json_decode($wechatResponse['content'], true);
                        $wechatContext = WechatContext::where(['openid' => $openid])->order('id', 'desc')->find();
                        $data = ['eventkey' => $eventkey, 'command' => '', 'refreshtime' => time(), 'openid' => $openid];
                        if ($wechatContext) {
                            $wechatContext->save($data);
                        } else {
                            $wechatContext = WechatContext::create($data, true);
                        }
                        $result = $wechatService->response($this, $openid, '', $responseContent, $wechatContext);
                        if ($result) {
                            return $result;
                        }
                    }
                    return $unknownMessage;
                case 'text': //文字消息
                case 'image': //图片消息
                case 'voice': //语音消息
                case 'video': //视频消息
                case 'location': //坐标消息
                case 'link': //链接消息
                default: //其它消息

                    //自动回复处理
                    if ($message['MsgType'] == 'text') {
                        $autoreply = null;
                        $autoreplyList = WechatAutoreply::where('status', 'normal')->cache(true)->order('weigh DESC,id DESC')->select();
                        foreach ($autoreplyList as $index => $item) {
                            //完全匹配和正则匹配
                            if ($item['text'] == $message['Content'] || (in_array(mb_substr($item['text'], 0, 1), ['#', '~', '/']) && preg_match($item['text'], $message['Content'], $matches))) {
                                $autoreply = $item;
                                break;
                            }
                        }

                        if ($autoreply) {
                            $wechatResponse = WechatResponse::where(["eventkey" => $autoreply['eventkey'], 'status' => 'normal'])->find();
                            if ($wechatResponse) {
                                $responseContent = (array)json_decode($wechatResponse['content'], true);
                                $wechatContext = WechatContext::where(['openid' => $openid])->order('id', 'desc')->find();
                                $result = $wechatService->response($this, $openid, $message['Content'], $responseContent, $wechatContext, $matches);
                                if ($result) {
                                    return $result;
                                }
                            }
                        }
                    }
                    return $unknownMessage;
            }
            return ""; //SUCCESS
        });

        $response = $this->app->server->serve();
        //file_put_contents("pcl_wct.log", date("Y-m-d H:i:s") . "::4-" . json_encode($response, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
        // 将响应输出
        $response->send();
        return;
    }

    /**
     * 登录回调
     */
    public function callback()
    {


    }

    /**
     * 支付回调
     */
    public function notify()
    {
        Log::record(file_get_contents('php://input'), "notify");
        $response = $this->app->handlePaidNotify(function ($message, $fail) {
            // 你的逻辑
            return true;
            // 或者错误消息
            $fail('Order not exists.');
        });

        $response->send();
        return;
    }

    /**
     * 获取Token
     */
    public static function getAccessToken()
    {
        $token = Session::get('wechat_access_token');
        if (!$token) {
            $config = get_addon_config('wechat');
            $params = [
                'grant_type' => 'client_credential',
                'appid' => $config['app_id'],
                'secret' => $config['secret'],
            ];
            $url = "https://api.weixin.qq.com/cgi-bin/token";
            $result = Http::sendRequest($url, $params, 'GET');
            if ($result['ret']) {
                $msg = (array)json_decode($result['msg'], true);
                if (isset($msg['access_token'])) {
                    $token = $msg['access_token'];
                    Session::set('wechat_access_token', $token, $msg['expires_in'] - 1);
                }
            }
        }
        return $token;
    }

    /**
     * 根据Openid获取用户信息
     * @param string $openid 微信OpenID
     * @return User|null
     */
    public static function getUserByOpenid($openid)
    {
        $third = Third::where('platform', 'wechat')->where('openid', $openid)->find();
        if ($third && $third->user_id) {
            return User::get($third->user_id);
        }
        return null;
    }

}