关键字回复

参考代码

<?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 addons\wechat\model\Subject\Subject;

use EasyWeChat\Factory;
use addons\wechat\library\Wechat as WechatService;
use addons\wechat\library\Config as ConfigService;
use EasyWeChat\Kernel\Messages\News;
use EasyWeChat\Kernel\Messages\NewsItem;
use EasyWeChat\Kernel\Messages\Text;
use think\Log;

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

    public $app = null;

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

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

            $matches = null;
            $openid = $message['FromUserName'];
            $to_openid = $message['ToUserName'];

            $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 : "欢迎来到测试号\n使用帮助\n1、发送城市名称,可搜索天气(广州天气)\n2、发送课程名称,可搜索相关课程(php课程)\n3、发送物流单号,可搜索商品物流进度(查物流:2023051111)\n4、发送商品名称,可搜索商品(商品:手机)";
                            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;
                                }
                            }
                        }
                    }

                    // 帮助菜单
                    $helpArr = ['h',1,'帮助','help'];

                    // 菜单内容
                    $content = "欢迎来到测试号\n使用帮助\n1、发送城市名称,可搜索天气(广州天气)\n2、发送课程名称,可搜索相关课程(php课程)\n3、发送物流单号,可搜索商品物流进度(查物流:2023051111)\n4、发送商品名称,可搜索商品(商品:手机)";

                    // 判断接收信息是否为帮助菜单
                    if(in_array($message['Content'],$helpArr))
                    {
                        return new Text($content);
                    }

                    // 通过关键字搜索php课程
                    if(strpos($message['Content'],'课程') !== false)
                    {
                        // 写一个正则能获取正确的课程名称
                        preg_match('/(.*)课程/',$message['Content'],$class);

                        $class = isset($class[1]) ? $class[1] : '';

                        $subject = Subject::where(['title' => ['like',"%$class%"]])->select();

                        if(!$subject)
                        {
                            return new Text('暂无此课程');
                        }

                        // 重组的数据存放这里
                        $data = [];

                        $cdn = config('site.url');

                        foreach($subject as $item)
                        {
                            $data[] = new NewsItem([
                                'title' => $item['title'],
                                'description' => $item['content'],
                                'image' => $item['thumb_cdn'],
                                'url' => $cdn . "/home/subject/subject/info?subjectid=".$item['id']
                            ]);
                        }

                        return new News($data);

                    }

                    // 天气
                    if(strpos($message['Content'],'天气') !== false)
                    {
                        // 获取城市名称
                        preg_match('/(.*)天气/',$message['Content'],$city);

                        $city = isset($city[1]) ? $city[1] : '';

                        // 判断该城市天气是否缓存
                        if(file_exists(ROOT_PATH.'public/Weather/'.$city.'.json'))
                        {
                            // 获取文件时间
                            $fileTime = filemtime(ROOT_PATH.'public/Weather/'.$city.'.json');

                            // 当前时间减去文件修改时间
                            $time = time() - $fileTime;

                            // 60 * 60 
                            if($time > 3600)
                            {
                                $this->getWeatherData($city);
                            }
                        }else{
                            $this->getWeatherData($city);
                        }

                        $data = file_get_contents(ROOT_PATH.'public/Weather/'.$city.'.json');

                        $data = json_decode($data,true);

                        // 获取result的数据
                        $data = $data['result'];

                        $output = "{$data['city']}当前天气情况:\n天气情况:{$data['realtime']['info']}\n温度:{$data['realtime']['temperature']}℃\n湿度:{$data['realtime']['humidity']}℃\n风向:{$data['realtime']['direct']}\n风力:{$data['realtime']['power']}\n空气质量指数:{$data['realtime']['aqi']}";


                        // 城市:
                        // 近5天天气情况:
                        //     2022-07-28:晴、南风、2/11℃
                        //     2022-07-28:晴、南风、2/11℃
                        //     2022-07-28:晴、南风、2/11℃
                        //     2022-07-28:晴、南风、2/11℃
                        //     2022-07-28:晴、南风、2/11℃

                        $output .= "\n近五天的天气情况:\n";

                        foreach($data['future'] as $item)
                        {
                            // 日期
                            $date = $item['date'];
                            // 天气情况
                            $weather = $item['weather'];
                            // 风向
                            $direct = $item['direct'];
                            // 温度
                            $temperature = $item['temperature'];

                            $output .= "$date : $weather 、$direct 、$temperature\n";
                        }

                        return new Text($output);
                    }

                    return $unknownMessage;
            }
            return ""; //SUCCESS
        });

        $response = $this->app->server->serve();
        // 将响应输出
        $response->send();
        return;
    }

    /**
     * 保存搜索城市天气数据
     * @param $city 城市名
    */
    protected function getWeatherData($city)
    {
        // 先检测存放天气数据的文件夹是否存在
        if (!is_dir(ROOT_PATH . 'public/Weather/')) {
            // 创建文件夹
            mkdir(ROOT_PATH . '/public/Weather');
        }

        // 天气Api
        $ApiUrl = "http://apis.juhe.cn/simpleWeather/query?city=$city&key=9ab6176129dbb280b54721e4da1a1e78";

        // 通过file_get_contents函数获取到数据 请求是get 不用设置头信息
        $result = file_get_contents($ApiUrl);

        $result = json_decode($result, true);

        // 根据粗错误码显示错误信息
        switch ($result['error_code']) {
            case 10011:
                return new Text('您当前请求过多,请稍后再试');

            case 10012:
                return new Text('当前请求过多,请稍后再试');

            case 10020:
                return new Text('该功能正在维护中');

            case 10021:
                return new Text('该功能停用~');

            case 207302:
                return new Text('查询不到该城市的相关信息');

            case 207301:
                return new Text('错误的查询城市名,请重新查询');

            case 207303:
                return new Text('网络错误,请重试');
        }

        // 保存数据 防止Api访问过多
        file_put_contents(ROOT_PATH . 'public/Weather/' . $city . '.json', json_encode($result));
    }
}
powered by GitbookEdit Time: 2024-06-06 18:25:40