diff --git a/app/Http/Admin/Views/course/edit_basic.volt b/app/Http/Admin/Views/course/edit_basic.volt
index e28afa78..bf0f5709 100644
--- a/app/Http/Admin/Views/course/edit_basic.volt
+++ b/app/Http/Admin/Views/course/edit_basic.volt
@@ -30,10 +30,10 @@
diff --git a/app/Http/Admin/Views/setting/oauth.volt b/app/Http/Admin/Views/setting/oauth.volt
new file mode 100644
index 00000000..15b714b7
--- /dev/null
+++ b/app/Http/Admin/Views/setting/oauth.volt
@@ -0,0 +1,24 @@
+{% extends 'templates/main.volt' %}
+
+{% block content %}
+
+
+
+
+
+ {{ partial('setting/oauth_qq') }}
+
+
+ {{ partial('setting/oauth_weixin') }}
+
+
+ {{ partial('setting/oauth_weibo') }}
+
+
+
+
+{% endblock %}
\ No newline at end of file
diff --git a/app/Http/Admin/Views/setting/oauth_qq.volt b/app/Http/Admin/Views/setting/oauth_qq.volt
new file mode 100644
index 00000000..2f0d2f9a
--- /dev/null
+++ b/app/Http/Admin/Views/setting/oauth_qq.volt
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/app/Http/Admin/Views/setting/oauth_weibo.volt b/app/Http/Admin/Views/setting/oauth_weibo.volt
new file mode 100644
index 00000000..c7ca6bae
--- /dev/null
+++ b/app/Http/Admin/Views/setting/oauth_weibo.volt
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/app/Http/Admin/Views/setting/oauth_weixin.volt b/app/Http/Admin/Views/setting/oauth_weixin.volt
new file mode 100644
index 00000000..4c08c355
--- /dev/null
+++ b/app/Http/Admin/Views/setting/oauth_weixin.volt
@@ -0,0 +1,35 @@
+
\ No newline at end of file
diff --git a/app/Http/Home/Controllers/ConnectController.php b/app/Http/Home/Controllers/ConnectController.php
new file mode 100644
index 00000000..d5dc0a74
--- /dev/null
+++ b/app/Http/Home/Controllers/ConnectController.php
@@ -0,0 +1,149 @@
+getAuthorizeUrl(ConnectModel::PROVIDER_QQ);
+
+ return $this->response->redirect($url, true);
+ }
+
+ /**
+ * @Get("/weixin", name="home.oauth.weixin")
+ */
+ public function weixinAction()
+ {
+ $service = new ConnectService();
+
+ $url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WEIXIN);
+
+ return $this->response->redirect($url, true);
+ }
+
+ /**
+ * @Get("/weibo", name="home.oauth.weibo")
+ */
+ public function weiboAction()
+ {
+ $service = new ConnectService();
+
+ $url = $service->getAuthorizeUrl(ConnectModel::PROVIDER_WEIBO);
+
+ return $this->response->redirect($url, true);
+ }
+
+ /**
+ * @Get("/qq/callback", name="home.oauth.qq_callback")
+ */
+ public function qqCallbackAction()
+ {
+ $service = new ConnectService();
+
+ if ($this->authUser->id > 0) {
+
+ $service->bindUser(ConnectModel::PROVIDER_QQ);
+
+ return $this->response->redirect(['for' => 'home.uc.account']);
+ }
+
+ $captcha = $service->getSettings('captcha');
+
+ $this->view->pick('connect/bind');
+ $this->view->setVar('captcha', $captcha);
+ $this->view->setVar('provider', ConnectModel::PROVIDER_QQ);
+ }
+
+ /**
+ * @Get("/weixin/callback", name="home.oauth.weixin_callback")
+ */
+ public function weixinCallbackAction()
+ {
+ $service = new ConnectService();
+
+ if ($this->authUser->id > 0) {
+
+ $service->bindUser(ConnectModel::PROVIDER_WEIXIN);
+
+ return $this->response->redirect(['for' => 'home.uc.account']);
+ }
+
+ $captcha = $service->getSettings('captcha');
+
+ $this->view->pick('connect/bind');
+ $this->view->setVar('captcha', $captcha);
+ $this->view->setVar('provider', ConnectModel::PROVIDER_QQ);
+ }
+
+ /**
+ * @Get("/weibo/callback", name="home.oauth.weibo_callback")
+ */
+ public function weiboCallbackAction()
+ {
+ $service = new ConnectService();
+
+ if ($this->authUser->id > 0) {
+
+ $service->bindUser(ConnectModel::PROVIDER_WEIBO);
+
+ return $this->response->redirect(['for' => 'home.uc.account']);
+ }
+
+ $captcha = $service->getSettings('captcha');
+
+ $this->view->pick('connect/bind');
+ $this->view->setVar('captcha', $captcha);
+ $this->view->setVar('provider', ConnectModel::PROVIDER_QQ);
+ }
+
+ /**
+ * @Get("/weibo/refuse", name="home.oauth.weibo_refuse")
+ */
+ public function weiboRefuseAction()
+ {
+ return $this->response->redirect(['for' => 'home.account.login']);
+ }
+
+ /**
+ * @Post("/bind/login", name="home.oauth.bind_login")
+ */
+ public function bindLoginAction()
+ {
+ $service = new ConnectService();
+
+ $service->bindLogin();
+
+ $location = $this->url->get(['for' => 'home.uc.index']);
+
+ return $this->jsonSuccess(['location' => $location]);
+ }
+
+ /**
+ * @Post("/bind/register", name="home.oauth.bind_register")
+ */
+ public function bindRegisterAction()
+ {
+ $service = new ConnectService();
+
+ $service->bindRegister();
+
+ $location = $this->url->get(['for' => 'home.uc.index']);
+
+ return $this->jsonSuccess(['location' => $location]);
+ }
+
+}
diff --git a/app/Http/Home/Controllers/UserConsoleController.php b/app/Http/Home/Controllers/UserConsoleController.php
index 5e159e0e..fcd07636 100644
--- a/app/Http/Home/Controllers/UserConsoleController.php
+++ b/app/Http/Home/Controllers/UserConsoleController.php
@@ -3,6 +3,8 @@
namespace App\Http\Home\Controllers;
use App\Services\Logic\User\Console\AccountInfo as AccountInfoService;
+use App\Services\Logic\User\Console\ConnectDelete as ConnectDeleteService;
+use App\Services\Logic\User\Console\ConnectList as ConnectListService;
use App\Services\Logic\User\Console\ConsultList as ConsultListService;
use App\Services\Logic\User\Console\CourseList as CourseListService;
use App\Services\Logic\User\Console\FavoriteList as FavoriteListService;
@@ -59,13 +61,17 @@ class UserConsoleController extends Controller
*/
public function accountAction()
{
+ $type = $this->request->getQuery('type', 'string', 'info');
+
$service = new AccountInfoService();
$captcha = $service->getSettings('captcha');
$account = $service->handle();
- $type = $this->request->getQuery('type', 'string', 'info');
+ $service = new ConnectListService();
+
+ $connects = $service->handle();
if ($type == 'info') {
$this->view->pick('user/console/account_info');
@@ -79,6 +85,7 @@ class UserConsoleController extends Controller
$this->view->setVar('captcha', $captcha);
$this->view->setVar('account', $account);
+ $this->view->setVar('connects', $connects);
}
/**
@@ -207,4 +214,23 @@ class UserConsoleController extends Controller
return $this->jsonSuccess($content);
}
+ /**
+ * @Post("/connect/{id:[0-9]+}/delete", name="home.uc.unconnect")
+ */
+ public function deleteConnectAction($id)
+ {
+ $service = new ConnectDeleteService();
+
+ $service->handle($id);
+
+ $location = $this->url->get(['for' => 'home.uc.account']);
+
+ $content = [
+ 'location' => $location,
+ 'msg' => '解除登录绑定成功',
+ ];
+
+ return $this->jsonSuccess($content);
+ }
+
}
diff --git a/app/Http/Home/Services/Connect.php b/app/Http/Home/Services/Connect.php
new file mode 100644
index 00000000..5cd53a95
--- /dev/null
+++ b/app/Http/Home/Services/Connect.php
@@ -0,0 +1,167 @@
+request->getPost();
+
+ $validator = new AccountValidator();
+
+ $user = $validator->checkUserLogin($post['account'], $post['password']);
+
+ $openUser = $this->getOpenUserInfo($post['code'], $post['stats'], $post['provider']);
+
+ $this->handleBindRelation($user, $openUser, $post['provider']);
+
+ $this->auth->saveAuthInfo($user);
+ }
+
+ public function bindRegister()
+ {
+ $post = $this->request->getPost();
+
+ $openUser = $this->getOpenUserInfo($post['code'], $post['state'], $post['provider']);
+
+ $registerService = new RegisterService();
+
+ $account = $registerService->handle();
+
+ $userRepo = new UserRepo();
+
+ $user = $userRepo->findById($account->id);
+
+ $this->handleBindRelation($user, $openUser, $post['provider']);
+
+ $this->auth->saveAuthInfo($user);
+ }
+
+ public function bindUser($provider)
+ {
+ $code = $this->request->getQuery('code', 'trim');
+ $state = $this->request->getQuery('state', 'trim');
+
+ $user = $this->getLoginUser();
+
+ $openUser = $this->getOpenUserInfo($code, $state, $provider);
+
+ $this->handleBindRelation($user, $openUser, $provider);
+ }
+
+ public function getAuthorizeUrl($provider)
+ {
+ $auth = $this->getAuth($provider);
+
+ return $auth->getAuthorizeUrl();
+ }
+
+ public function getAuth($provider)
+ {
+ $auth = null;
+
+ switch ($provider) {
+ case ConnectModel::PROVIDER_QQ:
+ $auth = $this->getQQAuth();
+ break;
+ case ConnectModel::PROVIDER_WEIXIN:
+ $auth = $this->getWeiXinAuth();
+ break;
+ case ConnectModel::PROVIDER_WEIBO:
+ $auth = $this->getWeiBoAuth();
+ break;
+ }
+
+ if (!$auth) {
+ throw new \Exception('Invalid OAuth Provider');
+ }
+
+ return $auth;
+ }
+
+ protected function getQQAuth()
+ {
+ $settings = $this->getSettings('oauth.qq');
+
+ return new QQAuth(
+ $settings['client_id'],
+ $settings['client_secret'],
+ $settings['redirect_uri']
+ );
+ }
+
+ protected function getWeiXinAuth()
+ {
+ $settings = $this->getSettings('oauth.weixin');
+
+ return new WeiXinAuth(
+ $settings['client_id'],
+ $settings['client_secret'],
+ $settings['redirect_uri']
+ );
+ }
+
+ protected function getWeiBoAuth()
+ {
+ $settings = $this->getSettings('oauth.weibo');
+
+ return new WeiBoAuth(
+ $settings['client_id'],
+ $settings['client_secret'],
+ $settings['redirect_uri']
+ );
+ }
+
+ protected function getOpenUserInfo($code, $state, $provider)
+ {
+ $auth = $this->getAuth($provider);
+
+ $auth->checkState($state);
+
+ $token = $auth->getAccessToken($code);
+
+ $openId = $auth->getOpenId($token);
+
+ return $auth->getUserInfo($token, $openId);
+ }
+
+ protected function handleBindRelation(UserModel $user, array $openUser, $provider)
+ {
+ $connectRepo = new ConnectRepo();
+
+ $connect = $connectRepo->findByOpenId($openUser['id'], $provider);
+
+ if ($connect) {
+
+ if ($connect->deleted == 1) {
+ $connect->deleted = 0;
+ $connect->update();
+ }
+
+ } else {
+
+ $connect = new ConnectModel();
+
+ $connect->user_id = $user->id;
+ $connect->open_id = $openUser['id'];
+ $connect->open_name = $openUser['name'];
+ $connect->open_avatar = $openUser['avatar'];
+ $connect->provider = $provider;
+
+ $connect->create();
+ }
+ }
+
+}
diff --git a/app/Http/Home/Views/account/login.volt b/app/Http/Home/Views/account/login.volt
index edd461b6..d1066422 100644
--- a/app/Http/Home/Views/account/login.volt
+++ b/app/Http/Home/Views/account/login.volt
@@ -27,6 +27,11 @@
·
忘记密码