* @date 2017/03/22 15:32 * * @method \WeChat\Card card() static 卡券管理 * @method \WeChat\Custom custom() static 客服消息处理 * @method \WeChat\Limit limit() static 接口调用频次限制 * @method \WeChat\Media media() static 微信素材管理 * @method \WeChat\Menu menu() static 微信素材管理 * @method \WeChat\Oauth oauth() static 微信网页授权 * @method \WeChat\Pay pay() static 微信支付商户 * @method \WeChat\Product product() static 商店管理 * @method \WeChat\Qrcode qrcode() static 二维码管理 * @method \WeChat\Receive receive() static 公众号推送管理 * @method \WeChat\Scan scan() static 扫一扫接入管理 * @method \WeChat\Script script() static 微信前端支持 * @method \WeChat\Shake shake() static 揺一揺周边 * @method \WeChat\Tags tags() static 用户标签管理 * @method \WeChat\Template template() static 模板消息 * @method \WeChat\User user() static 微信粉丝管理 * @method \WeChat\Wifi wifi() static 门店WIFI管理 * --- 小程序SDK加载 开始 --- * @method \WeMini\Account miniAccount() static 小程序账号管理 * @method \WeMini\Basic miniBasic() static 小程序基础信息设置 * @method \WeMini\Code miniCode() static 小程序代码管理 * @method \WeMini\Domain miniDomain() static 小程序域名管理 * @method \WeMini\Tester minitester() static 小程序成员管理 * @method \WeMini\User miniUser() static 小程序帐号管理 * @method \WeMini\Crypt miniCrypt() static 小程序数据加密处理管理 * @method \WeMini\Plugs miniPlugs() static 小程序插件管理 * @method \WeMini\Poi miniPoi() static 小程地址管理 * @method \WeMini\Qrcode miniQrcode() static 小程二维码管理 * @method \WeMini\Template miniTemplate() static 小程序模板消息 * @method \WeMini\Total miniTotal() static 小程序数据接口 * --- 小程序SDK加载 结束 --- * @method void wechat() static 第三方微信工具 * @method void config() static 第三方配置工具 * @method \WeOpen\Login login() static 第三方微信登录 * @method \WeOpen\Service service() static 第三方服务 */ class WechatService { /** * 接口类型模式 * @var string */ private static $type = 'WeChat'; /** * 切换接口为服务号模式 */ public static function setWeChatState() { self::$type = 'WeChat'; } /** * 切换接口为小程序模式 */ public static function setWeMiniState() { self::$type = 'WeMini'; } /** * 获取微信实例ID * @param string $name 实例对象名称 * @param string $type 接口实例类型 * @return SoapService|string * @throws Exception * @throws \think\exception\PDOException */ public static function instance($name, $type = null) { if (!in_array($type, ['WeChat', 'WeMini'])) { $type = self::$type; } switch (strtolower(sysconf('wechat_type'))) { case 'api': $config = [ 'token' => sysconf('wechat_token'), 'appid' => sysconf('wechat_appid'), 'appsecret' => sysconf('wechat_appsecret'), 'encodingaeskey' => sysconf('wechat_encodingaeskey'), 'mch_id' => sysconf('wechat_mch_id'), 'mch_key' => sysconf('wechat_partnerkey'), 'ssl_cer' => sysconf('wechat_cert_cert'), 'ssl_key' => sysconf('wechat_cert_key'), 'cachepath' => env('cache_path') . 'wechat' . DIRECTORY_SEPARATOR, ]; $class = "\\{$type}\\" . ucfirst(strtolower($name)); if (class_exists($class)) { return new $class($config); } throw new Exception("Class '{$class}' not found"); case 'thr': list($appid, $appkey) = [sysconf('wechat_thr_appid'), sysconf('wechat_thr_appkey')]; $token = strtolower("{$name}-{$appid}-{$appkey}-{$type}"); $location = config('wechat.service_url') . "/wechat/api.client/soap/{$token}.html"; $params = ['uri' => strtolower($name), 'location' => $location, 'trace' => true]; return new SoapService(null, $params); default: throw new Exception('请在后台配置微信对接授权模式!'); } } /** * 获取微信网页JSSDK * @param null|string $url JS签名地址 * @return array * @throws \WeChat\Exceptions\InvalidResponseException * @throws \WeChat\Exceptions\LocalCacheException * @throws \think\Exception * @throws \think\exception\PDOException */ public static function webJsSDK($url = null) { $signUrl = is_null($url) ? app('request')->url(true) : $url; switch (strtolower(sysconf('wechat_type'))) { case 'api': return WechatService::script()->getJsSign($signUrl); case 'thr': return WechatService::wechat()->jsSign($signUrl); default: throw new Exception('请在后台配置微信对接授权模式!'); } } /** * 初始化进入授权 * @param string $url 授权页面URL地址 * @param int $fullMode 授权公众号模式 * @param bool $isRedirect 是否进行跳转 * @return array * @throws \think\Exception * @throws \think\exception\PDOException */ public static function webOauth($url, $fullMode = 0, $isRedirect = true) { $appid = self::getAppid(); list($openid, $fansinfo) = [session("{$appid}_openid"), session("{$appid}_fansinfo")]; if ((empty($fullMode) && !empty($openid)) || (!empty($fullMode) && !empty($fansinfo))) { empty($fansinfo) || FansService::set($fansinfo); return ['openid' => $openid, 'fansinfo' => $fansinfo]; } switch (strtolower(sysconf('wechat_type'))) { case 'api': $wechat = self::oauth(); if (request()->get('state') !== $appid) { $snsapi = empty($fullMode) ? 'snsapi_base' : 'snsapi_userinfo'; $param = (strpos($url, '?') !== false ? '&' : '?') . 'rcode=' . encode($url); $OauthUrl = $wechat->getOauthRedirect($url . $param, $appid, $snsapi); $isRedirect && redirect($OauthUrl, [], 301)->send(); exit("window.location.href='{$OauthUrl}'"); } $token = $wechat->getOauthAccessToken(); if (isset($token['openid'])) { session("{$appid}_openid", $openid = $token['openid']); if (empty($fullMode) && request()->get('rcode')) { redirect(decode(request()->get('rcode')), [], 301)->send(); } session("{$appid}_fansinfo", $fansinfo = $wechat->getUserInfo($token['access_token'], $openid)); empty($fansinfo) || FansService::set($fansinfo); } redirect(decode(request()->get('rcode')), [], 301)->send(); break; case 'thr': $service = self::wechat(); $result = $service->oauth(session_id(), $url, $fullMode); session("{$appid}_openid", $openid = $result['openid']); session("{$appid}_fansinfo", $fansinfo = $result['fans']); if ((empty($fullMode) && !empty($openid)) || (!empty($fullMode) && !empty($fansinfo))) { empty($fansinfo) || FansService::set($fansinfo); return ['openid' => $openid, 'fansinfo' => $fansinfo]; } if ($isRedirect && !empty($result['url'])) { redirect($result['url'], [], 301)->send(); } exit("window.location.href='{$result['url']}'"); default: throw new Exception('请在后台配置微信对接授权模式!'); } } /** * 获取当前公众号的AppId * @return bool|string * @throws \think\Exception * @throws \think\exception\PDOException */ public static function getAppid() { switch (strtolower(sysconf('wechat_type'))) { case 'api': return sysconf('wechat_appid'); case 'thr': return sysconf('wechat_thr_appid'); default: throw new Exception('请在后台配置微信对接授权模式!'); } } /** * 魔术静态方法实现对象 * @param string $name * @param array $arguments * @return SoapService * @throws \think\Exception * @throws \think\exception\PDOException */ public static function __callStatic($name, $arguments) { if (substr($name, 0, 4) === 'mini') { self::setWeMiniState(); $name = substr($name, 4); } else { self::setWeChatState(); } return self::instance($name); } }