diff --git a/application/wechat/controller/Api.php b/application/wechat/controller/Api.php
index d93f1394d..03cfd9edd 100644
--- a/application/wechat/controller/Api.php
+++ b/application/wechat/controller/Api.php
@@ -14,8 +14,12 @@
 
 namespace app\wechat\controller;
 
-use handler\WechatHandler;
+use service\DataService;
+use service\WechatService;
 use think\Controller;
+use think\Db;
+use think\Log;
+use Wechat\WechatReceive;
 
 /**
  * 微信接口控制器
@@ -26,21 +30,234 @@ use think\Controller;
 class Api extends Controller
 {
 
+    /**
+     * 微信openid
+     * @var string
+     */
+    protected $openid;
+
+    /**
+     * 微信消息对象
+     * @var WechatReceive
+     */
+    protected $wechat;
+
     /**
      * 微信消息接口
      * @return string
-     * @throws \Exception
      */
     public function index()
     {
-        if (!extension_loaded('soap')) {
-            throw new \Exception('Not support soap.');
+        // 实例接口对象
+        $this->wechat = &load_wechat('Receive');
+        // 验证接口请求
+        if ($this->wechat->valid() === false) {
+            $msg = "{$this->wechat->errMsg}[{$this->wechat->errCode}]";
+            Log::error($msg);
+            return $msg;
+        }
+        // 获取消息来源用户OPENID
+        $this->openid = $this->wechat->getRev()->getRevFrom();
+        // 获取并同步粉丝信息到数据库
+        $this->_updateFansInfo(true);
+        // 分别执行对应类型的操作
+        switch ($this->wechat->getRev()->getRevType()) {
+            case WechatReceive::MSGTYPE_TEXT:
+                return $this->_keys("WechatKeys#keys#" . $this->wechat->getRevContent());
+            case WechatReceive::MSGTYPE_EVENT:
+                return $this->_event();
+            case WechatReceive::MSGTYPE_IMAGE:
+                return $this->_image();
+            case WechatReceive::MSGTYPE_LOCATION:
+                return $this->_location();
+            default:
+                return 'success';
         }
-        $handler = new WechatHandler();
-        $service = new \SoapServer(null, ['uri' => 'api', 'trace' => 0]);
-        $service->setObject($handler);
-        $service->handle();
     }
 
+    /**
+     * 关键字处理
+     * @param string $keys
+     * @param bool $isForce
+     * @return string
+     */
+    private function _keys($keys, $isForce = false)
+    {
+        list($table, $field, $value) = explode('#', $keys . '##');
+        if (is_array($info = Db::name($table)->where($field, $value)->find()) && isset($info['type'])) {
+            // 数据状态检查
+            if (array_key_exists('status', $info) && empty($info['status'])) {
+                return 'success';
+            }
+            switch ($info['type']) {
+                case 'customservice': // 多客服
+                    $this->wechat->sendCustomMessage(['touser' => $this->openid, 'msgtype' => 'text', 'text' => ['content' => $info['content']]]);
+                    return $this->wechat->transfer_customer_service()->reply(false, true);
+                case 'keys': // 关键字
+                    if (empty($info['content']) && empty($info['name'])) {
+                        return 'success';
+                    }
+                    return $this->_keys('wechat_keys#keys#' . (empty($info['content']) ? $info['name'] : $info['content']));
+                case 'text': // 文本消息
+                    if (empty($info['content']) && empty($info['name'])) {
+                        return 'success';
+                    }
+                    return $this->wechat->text($info['content'])->reply(false, true);
+                case 'news': // 图文消息
+                    if (empty($info['news_id'])) {
+                        return 'success';
+                    }
+                    return $this->_news($info['news_id']);
+                case 'music': // 音频消息
+                    if (empty($info['music_url']) || empty($info['music_title']) || empty($info['music_desc'])) {
+                        return 'success';
+                    }
+                    $media_id = empty($info['music_image']) ? '' : WechatService::uploadForeverMedia($info['music_image'], 'image');
+                    if (empty($media_id)) {
+                        return 'success';
+                    }
+                    return $this->wechat->music($info['music_title'], $info['music_desc'], $info['music_url'], $info['music_url'], $media_id)->reply(false, true);
+                case 'voice': // 语音消息
+                    if (empty($info['voice_url'])) {
+                        return 'success';
+                    }
+                    $media_id = WechatService::uploadForeverMedia($info['voice_url'], 'voice');
+                    if (empty($media_id)) {
+                        return 'success';
+                    }
+                    return $this->wechat->voice($media_id)->reply(false, true);
+                case 'image': // 图文消息
+                    if (empty($info['image_url'])) {
+                        return 'success';
+                    }
+                    $media_id = WechatService::uploadForeverMedia($info['image_url'], 'image');
+                    if (empty($media_id)) {
+                        return 'success';
+                    }
+                    return $this->wechat->image($media_id)->reply(false, true);
+                case 'video': // 视频消息
+                    if (empty($info['video_url']) || empty($info['video_desc']) || empty($info['video_title'])) {
+                        return 'success';
+                    }
+                    $data = ['title' => $info['video_title'], 'introduction' => $info['video_desc']];
+                    $media_id = WechatService::uploadForeverMedia($info['video_url'], 'video', true, $data);
+                    return $this->wechat->video($media_id, $info['video_title'], $info['video_desc'])->reply(false, true);
+            }
+        }
+        if ($isForce) {
+            return 'success';
+        }
+        return $this->_keys('wechat_keys#keys#default', true);
+    }
+
+    /**
+     * 回复图文
+     * @param int $news_id
+     * @return bool|string
+     */
+    protected function _news($news_id = 0)
+    {
+        if (is_array($newsinfo = WechatService::getNewsById($news_id)) && !empty($newsinfo['articles'])) {
+            $newsdata = [];
+            foreach ($newsinfo['articles'] as $vo) {
+                $newsdata[] = [
+                    'Title'       => $vo['title'],
+                    'Description' => $vo['digest'],
+                    'PicUrl'      => $vo['local_url'],
+                    'Url'         => url("@wechat/review", '', true, true) . "?content={$vo['id']}&type=article",
+                ];
+            }
+            return $this->wechat->news($newsdata)->reply(false, true);
+        }
+        return 'success';
+    }
+
+    /**
+     * 事件处理
+     */
+    protected function _event()
+    {
+        $event = $this->wechat->getRevEvent();
+        switch (strtolower($event['event'])) {
+            case 'subscribe': // 粉丝关注事件
+                $this->_updateFansInfo(true);
+                $this->_spread($event['key']);
+                return $this->_keys('wechat_keys#keys#subscribe', true);
+            case 'unsubscribe':// 粉丝取消关注
+                $this->_updateFansInfo(false);
+                return 'success';
+            case 'click': // 点击菜单事件
+                return $this->_keys($event['key']);
+            case 'scancode_push':
+            case 'scancode_waitmsg': // 扫码推事件
+                $scanInfo = $this->wechat->getRev()->getRevScanInfo();
+                if (isset($scanInfo['ScanResult'])) {
+                    return $this->_keys($scanInfo['ScanResult']);
+                }
+                return 'success';
+            case 'scan':
+                if (!empty($event['key'])) {
+                    return $this->_spread($event['key']);
+                }
+                return 'success';
+        }
+        return 'success';
+    }
+
+    /**
+     * 推荐好友扫码关注
+     * @param string $event
+     * @return mixed
+     */
+    private function _spread($event)
+    {
+        $key = preg_replace('|^.*?(\d+).*?$|', '$1', "{$event}");
+        // 检测推荐是否有效
+        $fans = Db::name('WechatFans')->where('id', $key)->find();
+        if (!is_array($fans) || !isset($fans['openid']) || $fans['openid'] === $this->openid) {
+            return false;
+        }
+        // 标识推荐关系
+        $data = ['spread_by' => $fans['openid'], 'spread_at' => date('Y-m-d H:i:s')];
+        Db::name('WechatFans')->where("openid='{$this->openid}' and (spread_openid is null or spread_openid='')")->setField($data);
+        // @todo 推荐成功的奖励
+    }
+
+    /**
+     * 位置事情回复
+     * @return string
+     */
+    private function _location()
+    {
+        return 'success';
+    }
+
+    /**
+     * 图片事件处理
+     */
+    private function _image()
+    {
+        return 'success';
+    }
+
+    /**
+     * 同步粉丝状态
+     * @param bool $subscribe 关注状态
+     */
+    protected function _updateFansInfo($subscribe = true)
+    {
+        if ($subscribe) {
+            $fans = WechatService::getFansInfo($this->openid);
+            if (empty($fans) || empty($fans['subscribe'])) {
+                $wechat = &load_wechat('User');
+                $userInfo = $wechat->getUserInfo($this->openid);
+                $userInfo['subscribe'] = intval($subscribe);
+                WechatService::setFansInfo($userInfo, $wechat->appid);
+            }
+        } else {
+            $data = ['subscribe' => '0', 'appid' => $this->wechat->appid, 'openid' => $this->openid];
+            DataService::save('wechat_fans', $data, ['appid', 'openid']);
+        }
+    }
 
 }