From 02983a27c9a9985edea01a9f032d4dd3e4b4214a Mon Sep 17 00:00:00 2001 From: xiaochong0302 Date: Wed, 26 Mar 2025 15:17:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=BE=AE=E4=BF=A1=E5=85=AC?= =?UTF-8?q?=E4=BC=97=E5=8F=B7=E7=9B=B8=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Home/Controllers/ConnectController.php | 3 - .../WeChatOfficialAccountController.php | 3 - .../Home/Services/WeChatOfficialAccount.php | 18 ++++ app/Repos/Connect.php | 23 ++--- app/Services/Logic/WeChat/OfficialAccount.php | 85 +++++++------------ 5 files changed, 58 insertions(+), 74 deletions(-) diff --git a/app/Http/Home/Controllers/ConnectController.php b/app/Http/Home/Controllers/ConnectController.php index 7479287a..9653c43d 100644 --- a/app/Http/Home/Controllers/ConnectController.php +++ b/app/Http/Home/Controllers/ConnectController.php @@ -135,12 +135,9 @@ class ConnectController extends Controller } } - $captcha = $service->getSettings('captcha'); - $this->seo->prependTitle('绑定帐号'); $this->view->pick('connect/bind'); - $this->view->setVar('captcha', $captcha); $this->view->setVar('provider', $provider); $this->view->setVar('open_user', $openUser); } diff --git a/app/Http/Home/Controllers/WeChatOfficialAccountController.php b/app/Http/Home/Controllers/WeChatOfficialAccountController.php index e52bd79d..ba2c3c84 100644 --- a/app/Http/Home/Controllers/WeChatOfficialAccountController.php +++ b/app/Http/Home/Controllers/WeChatOfficialAccountController.php @@ -24,12 +24,9 @@ class WeChatOfficialAccountController extends Controller */ public function bindAction() { - $captcha = $this->getSettings('captcha'); - $this->seo->prependTitle('绑定帐号'); $this->view->pick('wechat/oa/bind'); - $this->view->setVar('captcha', $captcha); } /** diff --git a/app/Http/Home/Services/WeChatOfficialAccount.php b/app/Http/Home/Services/WeChatOfficialAccount.php index b923ea91..92f6223c 100644 --- a/app/Http/Home/Services/WeChatOfficialAccount.php +++ b/app/Http/Home/Services/WeChatOfficialAccount.php @@ -14,6 +14,7 @@ use App\Repos\User as UserRepo; use App\Services\Auth\Home as AuthService; use App\Services\Logic\Account\Register as RegisterService; use App\Services\Logic\Notice\External\AccountLogin as AccountLoginNotice; +use App\Services\Logic\WeChat\OfficialAccount as WeChatOAService; use App\Validators\Account as AccountValidator; use App\Validators\WeChatOfficialAccount as WeChatOAValidator; @@ -63,10 +64,13 @@ class WeChatOfficialAccount extends Service $openId = $validator->checkLoginOpenId($post['ticket']); + $unionId = $this->getUnionId($openId); + $connect = new ConnectModel(); $connect->user_id = $user->id; $connect->open_id = $openId; + $connect->union_id = $unionId; $connect->provider = ConnectModel::PROVIDER_WECHAT_OA; $connect->create(); @@ -86,6 +90,8 @@ class WeChatOfficialAccount extends Service $openId = $validator->checkLoginOpenId($post['ticket']); + $unionId = $this->getUnionId($openId); + $registerService = new RegisterService(); $account = $registerService->handle(); @@ -98,6 +104,7 @@ class WeChatOfficialAccount extends Service $connect->user_id = $user->id; $connect->open_id = $openId; + $connect->union_id = $unionId; $connect->provider = ConnectModel::PROVIDER_WECHAT_OA; $connect->create(); @@ -111,6 +118,17 @@ class WeChatOfficialAccount extends Service $this->eventsManager->fire('Account:afterRegister', $this, $user); } + protected function getUnionId($openId) + { + $service = new WeChatOAService(); + + $app = $service->getOfficialAccount(); + + $user = $app->user->get($openId); + + return $user['unionid'] ?: ''; + } + protected function getAppAuth() { /** diff --git a/app/Repos/Connect.php b/app/Repos/Connect.php index bd687a9c..dfd4756a 100644 --- a/app/Repos/Connect.php +++ b/app/Repos/Connect.php @@ -29,8 +29,16 @@ class Connect extends Repository $query->andWhere('user_id = :user_id:', ['user_id' => $where['user_id']]); } + if (!empty($where['open_id'])) { + $query->andWhere('open_id = :open_id:', ['open_id' => $where['open_id']]); + } + if (!empty($where['provider'])) { - $query->andWhere('provider = :provider:', ['provider' => $where['provider']]); + if (is_array($where['provider'])) { + $query->inWhere('provider', $where['provider']); + } else { + $query->andWhere('provider = :provider:', ['provider' => $where['provider']]); + } } if (isset($where['deleted'])) { @@ -67,19 +75,6 @@ class Connect extends Repository ]); } - /** - * @param string $openId - * @param int $provider - * @return ConnectModel|Model|bool - */ - public function findByOpenIdShallow($openId, $provider) - { - return ConnectModel::findFirst([ - 'conditions' => 'open_id = ?1 AND provider = ?2', - 'bind' => [1 => $openId, 2 => $provider], - ]); - } - /** * @param int $userId * @param int $provider diff --git a/app/Services/Logic/WeChat/OfficialAccount.php b/app/Services/Logic/WeChat/OfficialAccount.php index 6038b560..eb75c483 100644 --- a/app/Services/Logic/WeChat/OfficialAccount.php +++ b/app/Services/Logic/WeChat/OfficialAccount.php @@ -111,6 +111,9 @@ class OfficialAccount extends AppService $logger->debug('Received Message: ' . json_encode($message)); + /** + * 事件类型文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html + */ switch ($message['MsgType']) { case 'event': switch ($message['Event']) { @@ -161,44 +164,24 @@ class OfficialAccount extends AppService if ($connect) return null; - /** - * 尼玛不知道为什么又多了个"qrscene_"前缀,SCAN事件里面又不带这个前缀 - */ + $loginScene = sprintf('qrscene_%s', self::QR_SCENE_LOGIN); + $subscribeScene = sprintf('qrscene_%s', self::QR_SCENE_SUBSCRIBE); - $userId = 0; - - if (Text::startsWith($eventKey, $subscribeScene)) { - - $userId = str_replace($subscribeScene, '', $eventKey); - - } else { - - $connect = $connectRepo->findByOpenIdShallow($openId, ConnectModel::PROVIDER_WECHAT_OA); - - if ($connect) $userId = $connect->user_id; + /** + * 未关注过服务号,在登录页扫登录场景码,关注服务号 + */ + if (Text::startsWith($eventKey, $loginScene)) { + $ticket = str_replace($loginScene, '', $eventKey); + $this->handleLoginPageSubscribe($ticket, $openId); } - if ($userId > 0) { - - $userRepo = new UserRepo(); - - $user = $userRepo->findById($userId); - - if (!$user) return null; - - $userInfo = $this->getUserInfo($openId); - - $unionId = $userInfo['unionid'] ?: ''; - - $connect = new ConnectModel(); - - $connect->user_id = $userId; - $connect->open_id = $openId; - $connect->union_id = $unionId; - $connect->provider = ConnectModel::PROVIDER_WECHAT_OA; - - $connect->create(); + /** + * 未关注过服务号,在用户中心扫关注场景码,关注服务号 + */ + if (Text::startsWith($eventKey, $subscribeScene)) { + $userId = str_replace($subscribeScene, '', $eventKey); + $this->handleAccountPageSubscribe($userId, $openId); } return new TextMessage('开心呀,我们又多了一个小伙伴!'); @@ -228,19 +211,19 @@ class OfficialAccount extends AppService $eventKey = $message['EventKey'] ?? ''; if (Text::startsWith($eventKey, self::QR_SCENE_LOGIN)) { - return $this->handleLoginScanEvent($eventKey, $openId); + $ticket = str_replace(self::QR_SCENE_LOGIN, '', $eventKey); + $this->handleLoginPageSubscribe($ticket, $openId); } elseif (Text::startsWith($eventKey, self::QR_SCENE_SUBSCRIBE)) { - return $this->handleSubscribeScanEvent($eventKey, $openId); + $userId = str_replace(self::QR_SCENE_SUBSCRIBE, '', $eventKey); + $this->handleAccountPageSubscribe($userId, $openId); } return $this->emptyReply(); } - protected function handleLoginScanEvent($eventKey, $openId) + protected function handleLoginPageSubscribe($ticket, $openId) { - $ticket = str_replace(self::QR_SCENE_LOGIN, '', $eventKey); - - if (empty($ticket) || empty($openId)) return null; + if (empty($ticket) || empty($openId)) return; $connectRepo = new ConnectRepo(); @@ -256,31 +239,27 @@ class OfficialAccount extends AppService ]; $cache->save($keyName, $content, 30 * 60); - - return $this->emptyReply(); } - protected function handleSubscribeScanEvent($eventKey, $openId) + protected function handleAccountPageSubscribe($userId, $openId) { - $userId = str_replace(self::QR_SCENE_SUBSCRIBE, '', $eventKey); - - if (empty($userId) || empty($openId)) return null; + if (empty($userId) || empty($openId)) return; $userRepo = new UserRepo(); $user = $userRepo->findById($userId); - if (!$user) return null; - - $userInfo = $this->getUserInfo($openId); - - $unionId = $userInfo['unionid'] ?: ''; + if (!$user) return; $connectRepo = new ConnectRepo(); $connect = $connectRepo->findByOpenId($openId, ConnectModel::PROVIDER_WECHAT_OA); - if ($connect) return null; + if ($connect) return; + + $userInfo = $this->getUserInfo($openId); + + $unionId = $userInfo['unionid'] ?: ''; $connect = new ConnectModel(); @@ -290,8 +269,6 @@ class OfficialAccount extends AppService $connect->provider = ConnectModel::PROVIDER_WECHAT_OA; $connect->create(); - - return $this->emptyReply(); } protected function handleClickEvent($message)