Browse Source

增加微信模块

Anyon 5 years ago
parent
commit
88d4e1c409

+ 0 - 92
app/service/controller/Fans.php

@@ -1,92 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\controller;
-
-use think\admin\Controller;
-
-/**
- * 微信粉丝管理
- * Class Fans
- * @package app\service\controller
- */
-class Fans extends Controller
-{
-    /**
-     * 绑定数据表
-     * @var string
-     */
-    protected $table = 'WechatFans';
-
-    /**
-     * 初始化函数
-     */
-    protected function initialize()
-    {
-        $this->appid = input('appid', $this->app->session->get('current_appid'));
-        if (empty($this->appid)) {
-            $this->where = ['status' => '1', 'service_type' => '2', 'is_deleted' => '0', 'verify_type' => '0'];
-            $this->appid = $this->app->db->name('WechatServiceConfig')->where($this->where)->value('authorizer_appid');
-        }
-        if (empty($this->appid)) {
-            $this->fetch('/not-auth');
-        } else {
-            $this->app->session->set('current_appid', $this->appid);
-        }
-        if ($this->request->isGet()) {
-            $this->where = ['status' => '1', 'service_type' => '2', 'is_deleted' => '0', 'verify_type' => '0'];
-            $this->wechats = $this->app->db->name('WechatServiceConfig')->where($this->where)->order('id desc')->column('authorizer_appid,nick_name');
-        }
-    }
-
-    /**
-     * 微信粉丝管理
-     * @auth true
-     * @menu true
-     */
-    public function index()
-    {
-        $this->title = '微信粉丝管理';
-        $query = $this->_query($this->table)->like('nickname')->equal('subscribe,is_black');
-        $query->dateBetween('subscribe_at')->where(['appid' => $this->appid])->order('subscribe_time desc')->page();
-    }
-
-    /**
-     * 列表数据处理
-     * @param array $data
-     */
-    protected function _index_page_filter(array &$data)
-    {
-        $tags = $this->app->db->name('WechatFansTags')->column('id,name');
-        foreach ($data as &$user) {
-            $user['tags'] = [];
-            foreach (explode(',', $user['tagid_list']) as $tagid) {
-                if (isset($tags[$tagid])) $user['tags'][] = $tags[$tagid];
-            }
-        }
-    }
-
-    /**
-     * 删除粉丝信息
-     * @auth true
-     * @throws \think\db\exception\DbException
-     */
-    public function remove()
-    {
-        $this->_applyFormToken();
-        $this->_delete($this->table);
-    }
-
-}

+ 0 - 71
app/service/controller/Wechat.php

@@ -1,71 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\controller;
-
-use think\admin\Controller;
-
-/**
- * 公众号授权管理
- * Class Wechat
- * @package app\service\controller
- */
-class Wechat extends Controller
-{
-    /**
-     * 绑定数据表
-     * @var string
-     */
-    protected $table = 'WechatServiceConfig';
-
-    /**
-     * 公众号授权管理
-     * @auth true
-     * @menu true
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function index()
-    {
-        $this->title = '公众号授权管理';
-        $query = $this->_query($this->table)->like('authorizer_appid,nick_name,principal_name');
-        $query = $query->equal('service_type,status')->dateBetween('create_at');
-        $query->where(['is_deleted' => '0'])->order('id desc')->page();
-    }
-
-    /**
-     * 修改公众号状态
-     * @auth true
-     * @throws \think\db\exception\DbException
-     */
-    public function state()
-    {
-        $this->_applyFormToken();
-        $this->_save($this->table, ['status' => input('status')]);
-    }
-
-    /**
-     * 删除公众号授权
-     * @auth true
-     * @throws \think\db\exception\DbException
-     */
-    public function remove()
-    {
-        $this->_applyFormToken();
-        $this->_delete($this->table);
-    }
-
-}

+ 0 - 78
app/service/controller/api/Client.php

@@ -1,78 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\controller\api;
-
-use app\service\service\WechatService;
-use think\admin\Controller;
-use think\Exception;
-
-/**
- * 接口获取实例化
- * Class Client
- * @package app\service\controller\api
- */
-class Client extends Controller
-{
-    /**
-     * YAR 接口标准对接
-     * @return string
-     */
-    public function yar()
-    {
-        try {
-            $service = new \Yar_Server($this->instance());
-            $service->handle();
-        } catch (\Exception $exception) {
-            return $exception->getMessage();
-        }
-    }
-
-    /**
-     * SOAP 接口标准对接
-     * @return string
-     */
-    public function soap()
-    {
-        try {
-            $service = new \SoapServer(null, ['uri' => 'thinkadmin']);
-            $service->setObject($this->instance());
-            $service->handle();
-        } catch (\Exception $exception) {
-            return $exception->getMessage();
-        }
-    }
-
-    /**
-     * 远程获取实例对象
-     * @return mixed|\Exception
-     */
-    private function instance()
-    {
-        try {
-            $data = json_decode(debase64url(input('token', '')), true);
-            list($class, $appid, $time, $nostr, $sign) = [$data['class'], $data['appid'], $data['time'], $data['nostr'], $data['sign']];
-            $wechat = $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $appid])->find();
-            if (empty($wechat)) throw new Exception("抱歉,该公众号{$appid}未授权!");
-            if (abs(time() - $data['time']) > 10) throw new Exception('抱歉,接口调用时差过大!');
-            if (md5("{$class}#{$appid}#{$wechat['appkey']}#{$time}#{$nostr}") !== $sign) {
-                throw new Exception("抱歉,该公众号{$appid}签名异常!");
-            }
-            return WechatService::__callStatic($class, [$appid]);
-        } catch (\Exception $exception) {
-            return new \Exception($exception->getMessage(), 404);
-        }
-    }
-}

+ 0 - 214
app/service/controller/api/Push.php

@@ -1,214 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\controller\api;
-
-use app\service\handle\PublishHandle;
-use app\service\handle\ReceiveHandle;
-use app\service\service\WechatService;
-use think\admin\Controller;
-use think\admin\service\SystemService;
-use WeOpen\Service;
-
-/**
- * 服务平台推送服务
- * Class Push
- * @package app\service\controller\api
- */
-class Push extends Controller
-{
-    /**
-     * 微信API推送事件处理
-     * @param string $appid
-     * @return string
-     * @throws \WeChat\Exceptions\InvalidDecryptException
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function notify($appid = '')
-    {
-        $appid = empty($appid) ? input('appid') : $appid;
-        if (in_array($appid, ['wx570bc396a51b8ff8', 'wxd101a85aa106f53e'])) {
-            # 全网发布接口测试
-            return PublishHandle::instance()->handler($appid);
-        } else {
-            # 常归接口正常服务
-            return ReceiveHandle::instance()->handler($appid);
-        }
-    }
-
-    /**
-     * 一、处理服务推送Ticket
-     * 二、处理取消公众号授权
-     * @return string
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function ticket()
-    {
-        try {
-            $server = WechatService::WeOpenService();
-            if (!($data = $server->getComonentTicket())) {
-                return "Ticket event handling failed.";
-            }
-        } catch (\Exception $e) {
-            return "Ticket event handling failed, {$e->getMessage()}";
-        }
-        if (!empty($data['AuthorizerAppid']) && isset($data['InfoType'])) {
-            # 授权成功通知
-            if ($data['InfoType'] === 'authorized') {
-                $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $data['AuthorizerAppid']])->update(['is_deleted' => '0']);
-            }
-            # 接收取消授权服务事件
-            if ($data['InfoType'] === 'unauthorized') {
-                $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $data['AuthorizerAppid']])->update(['is_deleted' => '1']);
-            }
-            # 授权更新通知
-            if ($data['InfoType'] === 'updateauthorized') {
-                $_GET['auth_code'] = $data['PreAuthCode'];
-                $this->applyAuth($server);
-            }
-        }
-        return 'success';
-    }
-
-    /**
-     * 微信代网页授权
-     * @throws \think\Exception
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     */
-    public function oauth()
-    {
-        list($mode, $appid, $enurl, $sessid) = [
-            $this->request->get('mode'), $this->request->get('state'),
-            $this->request->get('enurl'), $this->request->get('sessid'),
-        ];
-        $result = WechatService::WeOpenService()->getOauthAccessToken($appid);
-        if (empty($result['openid'])) throw new \think\Exception('网页授权失败, 无法进一步操作!');
-        $this->app->cache->set("{$appid}_{$sessid}_openid", $result['openid'], 3600);
-        if (!empty($mode)) {
-            $fans = WechatService::WeChatOauth($appid)->getUserInfo($result['access_token'], $result['openid']);
-            if (empty($fans)) throw new \think\Exception('网页授权信息获取失败, 无法进一步操作!');
-            $this->app->cache->set("{$appid}_{$sessid}_fans", $fans, 3600);
-        }
-        $this->redirect(debase64url($enurl));
-    }
-
-    /**
-     * 跳转到微信服务授权页面
-     * @return string
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function auth()
-    {
-        $this->source = input('source');
-        if (empty($this->source)) {
-            return '请传入回跳 source 参数 ( 请使用 enbase64url 加密 )';
-        }
-        $this->sourceUrl = debase64url($this->source);
-        if (empty($this->sourceUrl)) {
-            return '请传入回跳 source 参数 ( 请使用 enbase64url 加密 )';
-        }
-        # 预授权码不为空,则表示可以进行授权处理
-        $service = WechatService::WeOpenService();
-        if (($auth_code = $this->request->get('auth_code'))) {
-            return $this->applyAuth($service, $this->sourceUrl);
-        }
-        # 生成微信授权链接,使用刷新跳转到授权网页
-        $redirect = url("@service/api.push/auth", [], true, true) . "?source={$this->source}";
-        if (($redirect = $service->getAuthRedirect($redirect))) {
-            ob_clean();
-            header("Refresh:0;url={$redirect}");
-            return "<script>window.location.href='{$redirect}';</script><a href='{$redirect}'>跳转中...</a>";
-        }
-        # 生成微信授权链接失败
-        return "<h2>Failed to create authorization. Please return to try again.</h2>";
-    }
-
-    /**
-     * 公众号授权绑定数据处理
-     * @param Service $service 平台服务对象
-     * @param string $redirect 授权成功回跳地址
-     * @return string
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    private function applyAuth(Service $service, $redirect = null)
-    {
-        // 通过授权code换取公众号信息
-        $result = $service->getQueryAuthorizerInfo();
-        if (empty($result['authorizer_appid'])) {
-            return "接收微信第三方平台授权失败! ";
-        }
-        // 重新通过接口查询公众号参数
-        if (!($update = array_merge($result, $service->getAuthorizerInfo($result['authorizer_appid'])))) {
-            return '获取授权数据失败, 请稍候再试! ';
-        }
-        // 生成公众号授权参数
-        $update = array_merge($this->buildAuthData($update), [
-            'status' => '1', 'is_deleted' => '0', 'expires_in' => time() + 7000, 'create_at' => date('y-m-d H:i:s'),
-        ]);
-        // 微信接口APPKEY处理与更新
-        $config = $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $result['authorizer_appid']])->find();
-        $update['appkey'] = empty($config['appkey']) ? md5(uniqid('', true)) : $config['appkey'];
-        SystemService::instance()->save('WechatServiceConfig', $update, 'authorizer_appid');
-        if (!empty($redirect)) { // 带上appid与appkey跳转到应用
-            $split = stripos($redirect, '?') > 0 ? '&' : '?';
-            $realurl = preg_replace(['/appid=\w+/i', '/appkey=\w+/i', '/(\?\&)$/i'], ['', '', ''], $redirect);
-            return redirect("{$realurl}{$split}appid={$update['authorizer_appid']}&appkey={$update['appkey']}");
-        }
-    }
-
-    /**
-     * 生成公众号授权信息
-     * @param array $info
-     * @return array
-     */
-    private function buildAuthData(array $info)
-    {
-        $info = array_change_key_case($info, CASE_LOWER);
-        if (isset($info['func_info']) && is_array($info['func_info'])) {
-            $info['func_info'] = join(',', array_map(function ($tmp) {
-                return isset($tmp['funcscope_category']['id']) ? $tmp['funcscope_category']['id'] : 0;
-            }, $info['func_info']));
-        }
-        $info['business_info'] = serialize($info['business_info']);
-        $info['verify_type_info'] = join(',', $info['verify_type_info']);
-        $info['service_type_info'] = join(',', $info['service_type_info']);
-        // 微信类型:  0 代表订阅号, 2 代表服务号, 3 代表小程序
-        $info['service_type'] = intval($info['service_type_info']) === 2 ? 2 : 0;
-        if (!empty($info['miniprograminfo'])) {
-            $info['service_type'] = 3;
-            $info['miniprograminfo'] = serialize($info['miniprograminfo']);
-        }
-        // 微信认证: -1 代表未认证, 0 代表微信认证
-        $info['verify_type'] = intval($info['verify_type_info']) !== 0 ? -1 : 0;
-        return $info;
-    }
-}

+ 0 - 61
app/service/handle/PublishHandle.php

@@ -1,61 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\handle;
-
-use app\service\service\WechatService;
-use think\admin\Service;
-
-/**
- * 授权公众上线测试处理
- * Class PublishHandle
- * @package app\service\serivce
- */
-class PublishHandle extends Service
-{
-    /**
-     * 事件初始化
-     * @param string $appid
-     * @return string
-     * @throws \WeChat\Exceptions\InvalidDecryptException
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     */
-    public function handler($appid)
-    {
-        try {
-            $wechat = WechatService::WeChatReceive($appid);
-        } catch (\Exception $e) {
-            return "Wechat message handling failed, {$e->getMessage()}";
-        }
-        /* 分别执行对应类型的操作 */
-        switch (strtolower($wechat->getMsgType())) {
-            case 'text':
-                $receive = $wechat->getReceive();
-                if ($receive['Content'] === 'TESTCOMPONENT_MSG_TYPE_TEXT') {
-                    return $wechat->text('TESTCOMPONENT_MSG_TYPE_TEXT_callback')->reply([], true);
-                } else {
-                    $key = str_replace("QUERY_AUTH_CODE:", '', $receive['Content']);
-                    WechatService::WeOpenService()->getQueryAuthorizerInfo($key);
-                    return $wechat->text("{$key}_from_api")->reply([], true);
-                }
-            case 'event':
-                $receive = $wechat->getReceive();
-                return $wechat->text("{$receive['Event']}from_callback")->reply([], true);
-            default:
-                return 'success';
-        }
-    }
-}

+ 0 - 65
app/service/handle/ReceiveHandle.php

@@ -1,65 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\handle;
-
-use app\service\service\WechatService;
-use think\admin\Service;
-
-/**
- * 授权公众号消息转发处理
- * Class ReceiveHandle
- * @package app\service\serivce
- */
-class ReceiveHandle extends Service
-{
-    /**
-     * 事件初始化
-     * @param string $appid
-     * @return string
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function handler($appid)
-    {
-        try {
-            $wechat = WechatService::WeChatReceive($appid);
-        } catch (\Exception $exception) {
-            return "Wechat message handling failed, {$exception->getMessage()}";
-        }
-        // 验证微信配置信息
-        $config = $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $appid])->find();
-        if (empty($config) || empty($config['appuri'])) {
-            sysoplog('微信接口', $message = "微信{$appid}授权配置验证无效");
-            return $message;
-        }
-        try {
-            list($data, $openid) = [$wechat->getReceive(), $wechat->getOpenid()];
-            if (isset($data['EventKey']) && is_object($data['EventKey'])) $data['EventKey'] = (array)$data['EventKey'];
-            $input = ['openid' => $openid, 'appid' => $appid, 'receive' => serialize($data), 'encrypt' => intval($wechat->isEncrypt())];
-            if (is_string($result = http_post($config['appuri'], $input, ['timeout' => 30]))) {
-                if (is_array($json = json_decode($result, true))) {
-                    return $wechat->reply($json, true, $wechat->isEncrypt());
-                } else {
-                    return $result;
-                }
-            }
-        } catch (\Exception $exception) {
-            sysoplog('微信接口', "微信{$appid}接口调用异常,{$exception->getMessage()}");
-        }
-        return 'success';
-    }
-}

+ 0 - 58
app/service/service/ClientService.php

@@ -1,58 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\service;
-
-/**
- * Class ClientService
- * @package app\service\serivce
- */
-class ClientService extends WechatService
-{
-    /**
-     * 静态调用对象
-     * @param string $name 请求的类名
-     * @param array $arguments 调用参数
-     * @return mixed
-     * @throws \think\Exception
-     * @throws \SoapFault
-     */
-    public static function __callStatic($name, $arguments)
-    {
-        if (count($arguments) !== 2) {
-            throw new \think\Exception('请按顺序传入APPID及APPKEY两个参数!');
-        }
-        $serviceUri = 'http://127.0.0.1:1231';
-        list($appid, $appkey) = $arguments;
-        $data = ['class' => $name, 'appid' => $appid, 'time' => time(), 'nostr' => uniqid()];
-        $data['sign'] = md5("{$data['class']}#{$appid}#{$appkey}#{$data['time']}#{$data['nostr']}");
-        $token = enbase64url(json_encode($data, JSON_UNESCAPED_UNICODE));
-        if (class_exists('Yar_Client')) {
-            $url = "{$serviceUri}/service/api.client/yar?not_init_session=1&token={$token}";
-            $client = new \Yar_Client($url);
-        } else {
-            $url = "{$serviceUri}/service/api.client/soap?not_init_session=1&token={$token}";
-            $client = new \SoapClient(null, ['location' => $url, 'uri' => "thinkadmin"]);
-        }
-        try {
-            $exception = new \think\Exception($client->getMessage(), $client->getCode());
-        } catch (\Exception $exception) {
-            $exception = null;
-        }
-        if ($exception instanceof \Exception) throw $exception;
-        return $client;
-    }
-
-}

+ 0 - 135
app/service/service/ConfigService.php

@@ -1,135 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\service;
-
-use think\admin\Service;
-
-/**
- * 公众号授权配置
- * Class ConfigService
- * @package app\service\service
- */
-class ConfigService extends Service
-{
-    /**
-     * 当前微信APPID
-     * @var string
-     */
-    protected $appid;
-
-    /**
-     * 当前微信配置
-     * @var array
-     */
-    protected $config;
-
-    /**
-     * 授权配置初始化
-     * @param string $appid
-     * @return $this
-     * @throws \think\Exception
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function initialize(string $appid): Service
-    {
-        $this->appid = $appid;
-        $this->config = $this->app->db->name('wechatServiceConfig')->where(['authorizer_appid' => $appid])->find();
-        if (empty($this->config)) {
-            throw new \think\Exception("公众号{$appid}还没有授权!");
-        }
-        return $this;
-    }
-
-    /**
-     * 获取当前公众号配置
-     * @return array
-     */
-    public function getConfig()
-    {
-        return $this->config;
-    }
-
-    /**
-     * 设置微信接口通知URL地址
-     * @param string $notifyUri 接口通知URL地址
-     * @return boolean
-     * @throws \think\Exception
-     * @throws \think\db\exception\DbException
-     */
-    public function setApiNotifyUri($notifyUri)
-    {
-        if (empty($notifyUri)) throw new \think\Exception('请传入微信通知URL');
-        list($where, $data) = [['authorizer_appid' => $this->appid], ['appuri' => $notifyUri]];
-        return $this->app->db->name('WechatServiceConfig')->where($where)->update($data) !== false;
-    }
-
-    /**
-     * 更新接口Appkey(成功返回新的Appkey)
-     * @return bool|string
-     * @throws \think\db\exception\DbException
-     */
-    public function updateApiAppkey()
-    {
-        $data = ['appkey' => md5(uniqid())];
-        $this->app->db->name('WechatServiceConfig')->where(['authorizer_appid' => $this->appid])->update($data);
-        return $data['appkey'];
-    }
-
-    /**
-     * 获取公众号的配置参数
-     * @param string $name 参数名称
-     * @return array|string
-     */
-    public function config($name = null)
-    {
-        return WechatService::WeChatScript($this->appid)->config->get($name);
-    }
-
-    /**
-     * 微信网页授权
-     * @param string $sessid 当前会话id(可用session_id()获取)
-     * @param string $source 当前会话URL地址(需包含域名的完整URL地址)
-     * @param integer $type 网页授权模式(0静默模式,1高级授权)
-     * @return array|boolean
-     */
-    public function oauth($sessid, $source, $type = 0)
-    {
-        $fans = $this->app->cache->get("{$this->appid}_{$sessid}_fans");
-        $openid = $this->app->cache->get("{$this->appid}_{$sessid}_openid");
-        if (!empty($openid) && (empty($type) || !empty($fans))) {
-            return ['openid' => $openid, 'fans' => $fans, 'url' => ''];
-        }
-        $mode = empty($type) ? 'snsapi_base' : 'snsapi_userinfo';
-        $url = url('@service/api.push/oauth', [], true, true);
-        $params = ['mode' => $type, 'sessid' => $sessid, 'enurl' => enbase64url($source)];
-        $authurl = WechatService::WeOpenService()->getOauthRedirect($this->appid, $url . '?' . http_build_query($params), $mode);
-        return ['openid' => $openid, 'fans' => $fans, 'url' => $authurl];
-    }
-
-    /**
-     * 微信网页JS签名
-     * @param string $url 当前会话URL地址(需包含域名的完整URL地址)
-     * @return array|boolean
-     * @throws \WeChat\Exceptions\InvalidResponseException
-     * @throws \WeChat\Exceptions\LocalCacheException
-     */
-    public function jsSign($url)
-    {
-        return WechatService::WeChatScript($this->appid)->getJsSign($url);
-    }
-}

+ 0 - 184
app/service/service/WechatService.php

@@ -1,184 +0,0 @@
-<?php
-
-// +----------------------------------------------------------------------
-// | ThinkAdmin
-// +----------------------------------------------------------------------
-// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
-// +----------------------------------------------------------------------
-// | 官方网站: http://demo.thinkadmin.top
-// +----------------------------------------------------------------------
-// | 开源协议 ( https://mit-license.org )
-// +----------------------------------------------------------------------
-// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
-// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
-// +----------------------------------------------------------------------
-
-namespace app\service\service;
-
-use think\admin\Service;
-
-/**
- * Class WechatService
- * @package app\service\serivce
- *
- * @method \WeChat\Card WeChatCard($appid) static 微信卡券管理
- * @method \WeChat\Custom WeChatCustom($appid) static 微信客服消息
- * @method \WeChat\Limit WeChatLimit($appid) static 接口调用频次限制
- * @method \WeChat\Media WeChatMedia($appid) static 微信素材管理
- * @method \WeChat\Menu WeChatMenu($appid) static 微信菜单管理
- * @method \WeChat\Oauth WeChatOauth($appid) static 微信网页授权
- * @method \WeChat\Pay WeChatPay($appid) static 微信支付商户
- * @method \WeChat\Product WeChatProduct($appid) static 微信商店管理
- * @method \WeChat\Qrcode WeChatQrcode($appid) static 微信二维码管理
- * @method \WeChat\Receive WeChatReceive($appid) static 微信推送管理
- * @method \WeChat\Scan WeChatScan($appid) static 微信扫一扫接入管理
- * @method \WeChat\Script WeChatScript($appid) static 微信前端支持
- * @method \WeChat\Shake WeChatShake($appid) static 微信揺一揺周边
- * @method \WeChat\Tags WeChatTags($appid) static 微信用户标签管理
- * @method \WeChat\Template WeChatTemplate($appid) static 微信模板消息
- * @method \WeChat\User WeChatUser($appid) static 微信粉丝管理
- * @method \WeChat\Wifi WeChatWifi($appid) static 微信门店WIFI管理
- *
- * ----- WeMini -----
- * @method \WeMini\Account WeMiniAccount($appid) static 小程序账号管理
- * @method \WeMini\Basic WeMiniBasic($appid) static 小程序基础信息设置
- * @method \WeMini\Code WeMiniCode($appid) static 小程序代码管理
- * @method \WeMini\Domain WeMiniDomain($appid) static 小程序域名管理
- * @method \WeMini\Tester WeMinitester($appid) static 小程序成员管理
- * @method \WeMini\User WeMiniUser($appid) static 小程序帐号管理
- * --------------------
- * @method \WeMini\Crypt WeMiniCrypt($options = []) static 小程序数据加密处理
- * @method \WeMini\Delivery WeMiniDelivery($options = []) static 小程序即时配送
- * @method \WeMini\Image WeMiniImage($options = []) static 小程序图像处理
- * @method \WeMini\Logistics WeMiniLogistics($options = []) static 小程序物流助手
- * @method \WeMini\Message WeMiniMessage($options = []) static 小程序动态消息
- * @method \WeMini\Ocr WeMiniOcr($options = []) static 小程序ORC服务
- * @method \WeMini\Plugs WeMiniPlugs($options = []) static 小程序插件管理
- * @method \WeMini\Poi WeMiniPoi($options = []) static 小程序地址管理
- * @method \WeMini\Qrcode WeMiniQrcode($options = []) static 小程序二维码管理
- * @method \WeMini\Security WeMiniSecurity($options = []) static 小程序内容安全
- * @method \WeMini\Soter WeMiniSoter($options = []) static 小程序生物认证
- * @method \WeMini\Template WeMiniTemplate($options = []) static 小程序模板消息支持
- * @method \WeMini\Total WeMiniTotal($options = []) static 小程序数据接口
- *
- * ----- WePay -----
- * @method \WePay\Bill WePayBill($appid) static 微信商户账单及评论
- * @method \WePay\Order WePayOrder($appid) static 微信商户订单
- * @method \WePay\Refund WePayRefund($appid) static 微信商户退款
- * @method \WePay\Coupon WePayCoupon($appid) static 微信商户代金券
- * @method \WePay\Redpack WePayRedpack($appid) static 微信红包支持
- * @method \WePay\Transfers WePayTransfers($appid) static 微信商户打款到零钱
- * @method \WePay\TransfersBank WePayTransfersBank($appid) static 微信商户打款到银行卡
- *
- * ----- WeOpen -----
- * @method \WeOpen\Login WeOpenLogin() static 第三方微信登录
- * @method \WeOpen\Service WeOpenService() static 第三方服务
- *
- * ----- ThinkService -----
- * @method ConfigService ThinkAdminConfig($appid) static 平台服务配置
- */
-class WechatService extends Service
-{
-
-    /**
-     * 静态初始化对象
-     * @param string $name
-     * @param array $arguments
-     * @return mixed
-     * @throws \think\Exception
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public static function __callStatic($name, $arguments)
-    {
-        list($type, $class) = ['-', '-'];
-        foreach (['WeChat', 'WeMini', 'WeOpen', 'WePay', 'ThinkAdmin'] as $type) {
-            if (strpos($name, $type) === 0) {
-                list(, $class) = explode($type, $name);
-                break;
-            }
-        }
-        if ("{$type}{$class}" !== $name) {
-            throw new \think\Exception("class {$name} not defined.");
-        }
-        if (in_array($type, ['WeChat', 'WePay', 'WeMini', 'ThinkAdmin'])) {
-            if (empty($arguments[0])) {
-                throw new \think\Exception("Appid parameter must be passed in during initialization");
-            }
-        }
-        $classname = "\\{$type}\\{$class}";
-        if (in_array($type, ['WeChat', 'WeMini', 'WePay'])) {
-            return new $classname(self::instance()->getWechatConfig($arguments[0]));
-        } elseif ($type === 'ThinkAdmin' && $class === 'Config') {
-            return ConfigService::instance()->initialize($arguments[0]);
-        } elseif ($type === 'WeOpen') {
-            return new $classname(self::instance()->getServiceConfig());
-        } else {
-            throw new \think\Exception("class {$classname} not defined.");
-        }
-    }
-
-    /**
-     * 获取公众号配置参数
-     * @param string $authorizerAppid
-     * @return array
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function getWechatConfig($authorizerAppid)
-    {
-        $conifg = [
-            'appid'          => $authorizerAppid,
-            'token'          => sysconf('service.component_token'),
-            'appsecret'      => sysconf('service.component_appsecret'),
-            'encodingaeskey' => sysconf('service.component_encodingaeskey'),
-            'cache_path'     => $this->getCachePath(),
-        ];
-        $conifg['GetAccessTokenCallback'] = function ($authorizerAppid) {
-            $map = ['authorizer_appid' => $authorizerAppid];
-            $refreshToken = $this->app->db->name('WechatServiceConfig')->where($map)->value('authorizer_refresh_token');
-            if (empty($refreshToken)) throw new \think\Exception('The WeChat information is not configured.', '404');
-            // 刷新公众号原授权 AccessToken
-            $result = WechatService::WeOpenService()->refreshAccessToken($authorizerAppid, $refreshToken);
-            if (empty($result['authorizer_access_token']) || empty($result['authorizer_refresh_token'])) {
-                throw new \think\Exception($result['errmsg']);
-            }
-            // 更新公众号授权信息
-            $this->app->db->name('WechatServiceConfig')->where($map)->update([
-                'authorizer_access_token'  => $result['authorizer_access_token'],
-                'authorizer_refresh_token' => $result['authorizer_refresh_token'],
-            ]);
-            return $result['authorizer_access_token'];
-        };
-        return $conifg;
-    }
-
-    /**
-     * 获取服务平台配置参数
-     * @return array
-     * @throws \think\db\exception\DataNotFoundException
-     * @throws \think\db\exception\DbException
-     * @throws \think\db\exception\ModelNotFoundException
-     */
-    public function getServiceConfig()
-    {
-        return [
-            'cache_path'               => $this->getCachePath(),
-            'component_appid'          => sysconf('service.component_appid'),
-            'component_token'          => sysconf('service.component_token'),
-            'component_appsecret'      => sysconf('service.component_appsecret'),
-            'component_encodingaeskey' => sysconf('service.component_encodingaeskey'),
-        ];
-    }
-
-    /**
-     * 获取缓存目录
-     * @return string
-     */
-    private function getCachePath()
-    {
-        return $this->app->getRuntimePath() . 'wechat';
-    }
-}

+ 0 - 44
app/service/view/config/form.html

@@ -1,44 +0,0 @@
-<form onsubmit="return false;" action="{:request()->url()}" data-auto="true" method="post" class='layui-form layui-card' autocomplete="off">
-
-    <div class="layui-card-body padding-left-40">
-
-        <div class="layui-form-item">
-            <label class="relative block">
-                <span class="color-green font-w7">开放平台服务 AppID</span>
-                <input name="service.component_appid" required pattern="^.{18}$" maxlength="18" placeholder="请输入18位开放平台服务AppID" value="{:sysconf('service.component_appid')}" class="layui-input">
-            </label>
-            <p class="help-block">开放平台服务 AppID,需要在微信开放平台获取</p>
-        </div>
-
-        <div class="layui-form-item">
-            <label class="relative block">
-                <span class="color-green font-w7">开放平台服务 AppSecret</span>
-                <input name="service.component_appsecret" required pattern="^.{32}$" maxlength="32" placeholder="请输入32位开放平台服务AppSecret" value="{:sysconf('service.component_appsecret')}" class="layui-input">
-            </label>
-            <p class="help-block">开放平台服务 AppSecret,需要在微信开放平台获取</p>
-        </div>
-
-        <div class="layui-form-item">
-            <label class="relative block">
-                <span class="color-green font-w7">开放平台消息校验 Token</span>
-                <input name="service.component_token" required placeholder="请输入开放平台消息校验Token" value="{:sysconf('service.component_token')}" class="layui-input">
-            </label>
-            <p class="help-block">开发者在代替微信接收到消息时,用此 Token 来校验消息</p>
-        </div>
-
-        <div class="layui-form-item">
-            <label class="relative block">
-                <span class="color-green font-w7">开放平台消息加解密 AesKey</span>
-                <input name="service.component_encodingaeskey" required pattern="^.{43}$" maxlength="43" placeholder="请输入43位开放平台消息加解密Key" value="{:sysconf('service.component_encodingaeskey')}" class="layui-input">
-            </label>
-            <p class="help-block">在代替微信收发消息时使用,必须是长度为43位字母和数字组合的字符串</p>
-        </div>
-
-        <div class="hr-line-dashed"></div>
-
-        <div class="text-center padding-bottom-15 margin-bottom-20">
-            <button class="layui-btn" type="submit">保存配置</button>
-        </div>
-
-    </div>
-</form>

+ 0 - 98
app/service/view/config/index.html

@@ -1,98 +0,0 @@
-{extend name='../../admin/view/main'}
-
-{block name="button"}
-
-{if auth("edit")}
-<button data-modal="{:url('edit')}" class='layui-btn layui-btn-sm layui-btn-primary'>配置平台参数</button>
-{/if}
-
-{/block}
-
-{block name="content"}
-<div class="relative">
-
-    <div class="think-box-shadow border-0 margin-bottom-20">
-        强烈建议安装 YAR 扩展来实现接口通信,SOAP 不能正常显示接口的异常信息
-    </div>
-
-    <div class="think-box-shadow padding-right-40 padding-left-40">
-        <div class="layui-row layui-col-space18">
-            <div class="layui-col-md6">
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">开放平台服务</span>
-                    <span class="color-desc margin-left-5">AppID</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:sysconf('service.component_appid')}">
-                        <a data-copy="{:sysconf('service.component_appid')}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">开放平台服务 AppID,需要在微信开放平台获取</p>
-                </div>
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">开放平台服务</span>
-                    <span class="color-desc margin-left-5">AppSecret</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:sysconf('service.component_appsecret')}">
-                        <a data-copy="{:sysconf('service.component_appsecret')}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">开放平台服务 AppSecret,需要在微信开放平台获取</p>
-                </div>
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">开放平台消息校验</span>
-                    <span class="color-desc margin-left-5">Token</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:sysconf('service.component_token')}">
-                        <a data-copy="{:sysconf('service.component_token')}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">开发者在代替微信接收到消息时,用此 Token 来校验消息</p>
-                </div>
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">开放平台消息加解密</span>
-                    <span class="color-desc margin-left-5">AesKey</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:sysconf('service.component_encodingaeskey')}">
-                        <a data-copy="{:sysconf('service.component_encodingaeskey')}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">在代替微信收发消息时使用,必须是长度为43位字母和数字组合的字符串</p>
-                </div>
-            </div>
-
-            <div class="layui-col-md6">
-                <div class="layui-form-item">
-                    <p class="color-green font-w7">授权发起页域名</p>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:request()->host()}">
-                        <a data-copy="{:request()->host()}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">从本域名跳转到登录授权页才可以完成登录授权,无需填写域名协议前缀</p>
-                </div>
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">授权事件接收地址</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.push/ticket',[],false,true)}">
-                        <a data-copy="{:url('@service/api.push/ticket',[],false,true)}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">用于接收取消授权通知、授权成功通知、授权更新通知、接收 TICKET 凭据</p>
-                </div>
-                <div class="layui-form-item">
-                    <span class="color-green font-w7">微信消息与事件接收</span>
-                    <label class="relative block">
-                        <input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.push/notify/appid/\$APPID\$',[],false,true)}">
-                        <a data-copy="{:url('@service/api.push/notify/appid/\$APPID\$',[],false,true)}" class="fa fa-copy input-right-icon"></a>
-                    </label>
-                    <p class="help-block">通过该 URL 接收微信消息和事件推送,$APPID$ 将被替换为微信 AppId</p>
-                </div>
-                <div class="layui-form-item">
-                    <p class="color-green font-w7">客户端系统 Yar 模块接口</p>
-                    <label class="relative block"><input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.client/yar',[],false,true)}?token=TOKEN"></label>
-                    <p class="help-block">客户端 Yar 接口,TOKEN 包含 class appid time nostr sign 的加密内容</p>
-                </div>
-                <div class="layui-form-item">
-                    <p class="color-green font-w7">客户端系统 Soap 模块接口</p>
-                    <label class="relative block"><input disabled class="layui-input layui-bg-gray" value="{:url('@service/api.client/soap',[],false,true)}?token=TOKEN"></label>
-                    <p class="help-block">客户端 Soap 接口,TOKEN 包含 class appid time nostr sign 的加密内容</p>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-{/block}

+ 0 - 1
app/service/view/not-auth.html

@@ -1 +0,0 @@
-还没有授权,请授权公众号

+ 0 - 85
app/service/view/wechat/index.html

@@ -1,85 +0,0 @@
-{extend name='../../admin/view/main'}
-
-{block name="button"}
-
-{if auth("syncall")}
-<button data-load="{:url('syncall')}" class='layui-btn layui-btn-sm layui-btn-primary'>同步所有授权</button>
-{/if}
-
-{/block}
-
-{block name="content"}
-<div class="think-box-shadow">
-    {include file='wechat/index_search'}
-    <table class="layui-table margin-top-10" lay-skin="line">
-        {notempty name='list'}
-        <thead>
-        <tr>
-            <th class='text-left nowrap' style="width:390px">接口信息</th>
-            <th class='text-left nowrap' style="width:120px">服务号信息</th>
-            <th class='text-left nowrap'></th>
-            <th class='text-left nowrap'></th>
-        </tr>
-        </thead>
-        {/notempty}
-        <tbody>
-        {foreach $list as $key=>$vo}
-        <tr>
-            <td class='text-left nowrap'>
-                <div class="inline-block text-top margin-right-5">
-                    <img alt="" style="width:60px;height:60px" data-tips-text="微信头像" data-tips-image src="{$vo.head_img|default=''}">
-                </div>
-                <div class="inline-block">
-                    公众号APPID:{$vo.authorizer_appid}&nbsp;&nbsp;&nbsp;&nbsp;调用次数:{$vo.total}<br>
-                    接口授权密钥:{$vo.appkey|default='<span class="color-desc">未生成接口服务密码, 请稍候授权绑定</span>'|raw}<br>
-                    消息推送接口:{$vo.appuri|default='<span class="color-desc">未配置消息推送接口</span>'|raw}
-                </div>
-            </td>
-            <td class='text-left nowrap'>
-                <div class="inline-block text-top margin-right-5">
-                    <img onerror="this.src='__ROOT__/static/theme/img/404_icon.png'" style="width:60px;height:60px" data-tips-text="微信二维码" data-tips-image src="{$vo.qrcode_url|local_image}">
-                </div>
-                <div class="inline-block">
-                    昵称:{$vo.nick_name|default='<span class="color-desc">未获取到公众号昵称</span>'|raw}<br>
-                    公司:{$vo.principal_name|default='<span class="color-desc">未获取到公司名字</span>'|raw}<br>
-                    状态:{if $vo.service_type eq 2}服务号{elseif $vo.service_type eq 3}小程序{else}订阅号{/if} /
-                    {$vo.verify_type == -1 ? '<span class="color-red">未认证</span>' : '<span class="color-green">已认证</span>'} /
-                    {if $vo.status eq 0}<span class="color-red">已禁用</span>{elseif $vo.status eq 1}<span class="color-green">使用中</span>{/if}
-                </div>
-            </td>
-            <td class="text-left nowrap">
-                账号:{$vo.user_name|default='--'}<br>
-                日期:{$vo.create_at|format_datetime|str_replace=' ','<br>时间:',###|raw}
-            </td>
-            <td class='text-left nowrap'>
-
-                {if $vo.status eq 1 and auth("state")}
-                <a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('state')}" data-csrf="{:systoken('state')}" data-value="id#{$vo.id};status#0">禁 用</a>
-                {elseif auth("state")}
-                <a class="layui-btn layui-btn-sm layui-btn-warm" data-action="{:url('state')}" data-csrf="{:systoken('state')}" data-value="id#{$vo.id};status#1">启 用</a>
-                {/if}
-
-
-                {if auth("remove")}
-                <a class="layui-btn layui-btn-sm layui-btn-danger" data-confirm="确定要删除该公众号吗?" data-action="{:url('remove')}" data-csrf="{:systoken('remove')}" data-value="id#{$vo.id}">删 除</a>
-                {/if}
-
-                {if auth("sync")}
-                <a class="layui-btn layui-btn-sm" data-load='{:url("sync")}?appid={$vo.authorizer_appid}'>同 步</a>
-                {/if}
-
-                {if auth("clearquota")}
-                <a class="layui-btn layui-btn-sm layui-btn-primary" data-confirm="每个公众号每个月有10次清零机会,请谨慎使用!" data-load='{:url("clearquota")}?appid={$vo.authorizer_appid}'>清 零</a>
-                {/if}
-
-            </td>
-        </tr>
-        {/foreach}
-        </tbody>
-    </table>
-
-    {empty name='list'}<span class="notdata">没有记录哦</span>{else}{$pagehtml|raw|default=''}{/empty}
-
-</div>
-
-{/block}

+ 0 - 76
app/service/view/wechat/index_search.html

@@ -1,76 +0,0 @@
-<fieldset>
-
-    <legend>条件搜索</legend>
-
-    <form class="layui-form layui-form-pane form-search" action="{:request()->url()}" onsubmit="return false" method="get" autocomplete="off">
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">微信标识</label>
-            <div class="layui-input-inline">
-                <input name="authorizer_appid" value="{:input('authorizer_appid','')}" placeholder="请输入微信APPID" class="layui-input">
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">微信名称</label>
-            <div class="layui-input-inline">
-                <input name="nick_name" value="{:input('nick_name','')}" placeholder="请输入微信名称" class="layui-input">
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">类型过滤</label>
-            <div class="layui-input-inline">
-                <select name="service_type" class="layui-select">
-                    <option value="">- 全部 -</option>
-                    {foreach ['0'=>'显示订阅号类型','2'=>'显示服务号类型','3'=>'显示小程序类型'] as $k=>$v}
-                    <!--{if $k.'' eq input('service_type','')}-->
-                    <option selected value="{$k}">{$v}</option>
-                    <!--{else}-->
-                    <option value="{$k}">{$v}</option>
-                    <!--{/if}-->
-                    {/foreach}
-                </select>
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">使用状态</label>
-            <div class="layui-input-inline">
-                <select class="layui-select" name="status">
-                    {foreach [''=>'- 全部 -','0'=>'已禁用的账号','1'=>'使用中的账号'] as $k=>$v}
-                    {if input('status') eq $k}
-                    <option selected value="{$k}">{$v}</option>
-                    {else}
-                    <option value="{$k}">{$v}</option>
-                    {/if}
-                    {/foreach}
-                </select>
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">注册公司</label>
-            <div class="layui-input-inline">
-                <input name="principal_name" value="{:input('principal_name','')}" placeholder="请输入注册公司" class="layui-input">
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <label class="layui-form-label">授权时间</label>
-            <div class="layui-input-inline">
-                <input data-date-range name="create_at" value="{:input('create_at','')}" placeholder="请选择授权时间" class="layui-input">
-            </div>
-        </div>
-
-        <div class="layui-form-item layui-inline">
-            <button class="layui-btn layui-btn-primary"><i class="layui-icon">&#xe615;</i> 搜 索</button>
-        </div>
-
-    </form>
-
-</fieldset>
-
-<script>
-    window.form.render();
-</script>

+ 10 - 26
app/service/controller/Config.php → app/wechat/controller/Fans.php

@@ -13,51 +13,35 @@
 // | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
 // +----------------------------------------------------------------------
 
-namespace app\service\controller;
+namespace app\wechat\controller;
 
 use think\admin\Controller;
 
 /**
- * 开放平台参数配置
- * Class Config
- * @package app\service\controller
+ * 微信粉丝管理
+ * Class Fans
+ * @package app\wechat\controller
  */
-class Config extends Controller
+class Fans extends Controller
 {
     /**
      * 绑定数据表
      * @var string
      */
-    protected $table = 'WechatServiceConfig';
+    protected $table = 'wechatFans';
 
     /**
-     * 开放平台配置
+     * 微信粉丝管理
      * @auth true
      * @menu true
-     */
-    public function index()
-    {
-        $this->title = '开放平台参数配置';
-        $this->fetch();
-    }
-
-    /**
-     * 修改开放平台参数
-     * @auth true
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\DbException
      * @throws \think\db\exception\ModelNotFoundException
      */
-    public function edit()
+    public function index()
     {
-        $this->_applyFormToken();
-        if ($this->request->isGet()) {
-            $this->fetch('form');
-        } else {
-            $post = $this->request->post();
-            foreach ($post as $k => $v) sysconf($k, $v);
-            $this->success('参数修改成功!');
-        }
+        $this->title = '微信粉丝管理';
+        $this->_query($this->table)->order('id desc')->page();
     }
 
 }

+ 150 - 0
app/wechat/service/WechatService.php

@@ -0,0 +1,150 @@
+<?php
+
+// +----------------------------------------------------------------------
+// | ThinkAdmin
+// +----------------------------------------------------------------------
+// | 版权所有 2014~2019 广州楚才信息科技有限公司 [ http://www.cuci.cc ]
+// +----------------------------------------------------------------------
+// | 官方网站: http://demo.thinkadmin.top
+// +----------------------------------------------------------------------
+// | 开源协议 ( https://mit-license.org )
+// +----------------------------------------------------------------------
+// | gitee 代码仓库:https://gitee.com/zoujingli/ThinkAdmin
+// | github 代码仓库:https://github.com/zoujingli/ThinkAdmin
+// +----------------------------------------------------------------------
+
+namespace app\wechat\service;
+
+use think\admin\Service;
+
+/**
+ * Class WechatService
+ * @package app\wechat\serivce
+ *
+ * @method \WeChat\Card WeChatCard() static 微信卡券管理
+ * @method \WeChat\Custom WeChatCustom() static 微信客服消息
+ * @method \WeChat\Limit WeChatLimit() static 接口调用频次限制
+ * @method \WeChat\Media WeChatMedia() static 微信素材管理
+ * @method \WeChat\Menu WeChatMenu() static 微信菜单管理
+ * @method \WeChat\Oauth WeChatOauth() static 微信网页授权
+ * @method \WeChat\Pay WeChatPay() static 微信支付商户
+ * @method \WeChat\Product WeChatProduct() static 微信商店管理
+ * @method \WeChat\Qrcode WeChatQrcode() static 微信二维码管理
+ * @method \WeChat\Receive WeChatReceive() static 微信推送管理
+ * @method \WeChat\Scan WeChatScan() static 微信扫一扫接入管理
+ * @method \WeChat\Script WeChatScript() static 微信前端支持
+ * @method \WeChat\Shake WeChatShake() static 微信揺一揺周边
+ * @method \WeChat\Tags WeChatTags() static 微信用户标签管理
+ * @method \WeChat\Template WeChatTemplate() static 微信模板消息
+ * @method \WeChat\User WeChatUser() static 微信粉丝管理
+ * @method \WeChat\Wifi WeChatWifi() static 微信门店WIFI管理
+ *
+ * ----- WeMini -----
+ * @method \WeMini\Account WeMiniAccount() static 小程序账号管理
+ * @method \WeMini\Basic WeMiniBasic() static 小程序基础信息设置
+ * @method \WeMini\Code WeMiniCode() static 小程序代码管理
+ * @method \WeMini\Domain WeMiniDomain() static 小程序域名管理
+ * @method \WeMini\Tester WeMinitester() static 小程序成员管理
+ * @method \WeMini\User WeMiniUser() static 小程序帐号管理
+ * --------------------
+ * @method \WeMini\Crypt WeMiniCrypt() static 小程序数据加密处理
+ * @method \WeMini\Delivery WeMiniDelivery() static 小程序即时配送
+ * @method \WeMini\Image WeMiniImage() static 小程序图像处理
+ * @method \WeMini\Logistics WeMiniLogistics() static 小程序物流助手
+ * @method \WeMini\Message WeMiniMessage() static 小程序动态消息
+ * @method \WeMini\Ocr WeMiniOcr() static 小程序ORC服务
+ * @method \WeMini\Plugs WeMiniPlugs() static 小程序插件管理
+ * @method \WeMini\Poi WeMiniPoi() static 小程序地址管理
+ * @method \WeMini\Qrcode WeMiniQrcode() static 小程序二维码管理
+ * @method \WeMini\Security WeMiniSecurity() static 小程序内容安全
+ * @method \WeMini\Soter WeMiniSoter() static 小程序生物认证
+ * @method \WeMini\Template WeMiniTemplate() static 小程序模板消息支持
+ * @method \WeMini\Total WeMiniTotal() static 小程序数据接口
+ *
+ * ----- WePay -----
+ * @method \WePay\Bill WePayBill() static 微信商户账单及评论
+ * @method \WePay\Order WePayOrder() static 微信商户订单
+ * @method \WePay\Refund WePayRefund() static 微信商户退款
+ * @method \WePay\Coupon WePayCoupon() static 微信商户代金券
+ * @method \WePay\Redpack WePayRedpack() static 微信红包支持
+ * @method \WePay\Transfers WePayTransfers() static 微信商户打款到零钱
+ * @method \WePay\TransfersBank WePayTransfersBank() static 微信商户打款到银行卡
+ *
+ * ----- WeOpen -----
+ * @method \WeOpen\Login WeOpenLogin() static 第三方微信登录
+ * @method \WeOpen\Service WeOpenService() static 第三方服务
+ *
+ * ----- ThinkService -----
+ * @method mixed ThinkAdminConfig($appid) static 平台服务配置
+ */
+class WechatService extends Service
+{
+
+    /**
+     * 静态初始化对象
+     * @param string $name
+     * @param array $arguments
+     * @return mixed
+     * @throws \SoapFault
+     * @throws \think\Exception
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public static function __callStatic($name, $arguments)
+    {
+        if (sysconf('wechat.type') === 'api') {
+            list($type, $class) = ['-', '-'];
+            foreach (['WeChat', 'WeMini', 'WeOpen', 'WePay', 'ThinkAdmin'] as $type) {
+                if (strpos($name, $type) === 0) {
+                    list(, $class) = explode($type, $name);
+                    break;
+                }
+            }
+            if ("{$type}{$class}" !== $name) {
+                throw new \think\Exception("class {$name} not defined.");
+            }
+            $classname = "\\{$type}\\{$class}";
+            return new $classname(self::instance()->getConfig());
+        } else {
+            list($appid, $appkey) = [sysconf('wechat.appid'), sysconf('wechat.appkey')];
+            $data = ['class' => $name, 'appid' => $appid, 'time' => time(), 'nostr' => uniqid()];
+            $data['sign'] = md5("{$data['class']}#{$appid}#{$appkey}#{$data['time']}#{$data['nostr']}");
+            $token = enbase64url(json_encode($data, JSON_UNESCAPED_UNICODE));
+            if (class_exists('Yar_Client')) {
+                $url = "http://open.cuci.cc/service/api.client/yar?not_init_session=1&token={$token}";
+                $client = new \Yar_Client($url);
+            } else {
+                $url = "http://open.cuci.cc/service/api.client/soap?not_init_session=1&token={$token}";
+                $client = new \SoapClient(null, ['location' => $url, 'uri' => "thinkadmin"]);
+            }
+            try {
+                $exception = new \think\Exception($client->getMessage(), $client->getCode());
+            } catch (\Exception $exception) {
+                $exception = null;
+            }
+            if ($exception instanceof \Exception) {
+                throw $exception;
+            }
+            return $client;
+        }
+    }
+
+    /**
+     * 获取公众号配置参数
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function getConfig()
+    {
+        return [
+            'token'          => sysconf('wechat.token'),
+            'appid'          => sysconf('wechat.appid'),
+            'appsecret'      => sysconf('service.appsecret'),
+            'encodingaeskey' => sysconf('service.encodingaeskey'),
+            'cache_path'     => $this->app->getRuntimePath() . 'wechat',
+        ];
+    }
+}