services->setting->mall->get($config['mall_id'], 'wechat'); if ($wechat) { \Yii::$app->params['wechatConfig'] = [ 'app_id' => $wechat['app_id'] ?? '', 'secret' => $wechat['secret'] ?? '', 'token' => $wechat['token'] ?? '', 'aes_key' => $wechat['aes_key'] ?? '', ]; } $mini_program = \Yii::$app->services->setting->mall->get($config['mall_id'], 'mini_program'); if (!empty($mini_program)) { \Yii::$app->params['wechatMiniProgramConfig'] = [ 'app_id' => $mini_program['app_id'], 'secret' => $mini_program['secret'], 'key' => $mini_program['pay_secret'] ?? '', 'cert_path' => $mini_program['cert_pem_path'] ?? '', 'key_path' => $mini_program['key_pem_path'] ?? '', 'notify_url' => ''//回调地址 ]; } $payment = \Yii::$app->services->setting->mall->get($config['mall_id'], 'pay.wechat'); $payment = json_decode($payment, true); if (!empty($payment["wechat_status"]) && $payment["wechat_status"] == 1) { $wechatOpenAppId = isset($payment['wechat_open_app_id']) ? $payment['wechat_open_app_id'] : ""; \Yii::$app->params['wechatPaymentConfig'] = [ 'app_id' => $payment['wechat_app_id']??0, 'mch_id' => $payment['wechat_mch_id']??0, 'key' => $payment['wechat_pay_secret']??'', 'cert_path' => $payment['wechat_cert_pem_path']??'', 'key_path' => $payment['wechat_key_pem_path']??'', 'notify_url' => ''//回调地址 ]; } } /** * @desc:app端微信授权登录,不登录,等关联手机号再进行登录 * @Author: hua * @Date: 2021/10/22 * @Time: 14:53 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false */ public function appAuthLogin($params) { try { //前端授权登录成功后,发送的用户数据 $result_data = json_decode($params["userData"], true); if (empty($result_data)) throw new Exception('授权失败'); //授权成功获取用户数据 {"userInfo":{"openId":"","nickName":"","gender":0,"city":"","province":"","country":"","avatarUrl":"","unionId":""}} $params["openid"] = $result_data["openId"]; $params["unionid"] = $result_data["unionId"]; $params["nickname"] = $result_data["nickName"] ?? '微信用户'; $params["headimgurl"] = $result_data["avatarUrl"]; $params['platform'] = User::PLATFORM_APP; $data["nickName"] = $params["nickname"]; $data["avatarUrl"] = $params["headimgurl"] ; $params['platform_data'] = $data; \Yii::error('appAuthLogin:'.json_encode($data)); $result = self::checkIsAuthorized($params); if (empty($result)) throw new Exception(self::getStaticError()); $return_data['openid'] = $params["openid"]; if (!empty($result['user'])) { $user = $result['user']; \Yii::$app->user->login($user); $res = \Yii::$app->services->apiAccessToken->getAccessToken($user, 'api'); $return_data['access_token'] = $res['access_token']; // 触发登录成功事件,事务提交完成后触发 $event = new UserLoginEvent($user['mall_id']); \Yii::$app->services->events->dispatch($event, [ 'mall_id' => $user['mall_id'], 'nickname' => $user['nickname'], 'user_id' => $user['id'], 'platform' => $user['platform'], 'ip' => ArrayHelper::get_client_ip(), 'device_type' => $params['device_type'] ?? '', 'device_mac' => $params['device_mac'] ?? '', ], $event->listeners); } return $return_data; } catch (\Exception $e) { \Yii::error("appAuthLogin error=" . $e->getFile() . ";line:" . $e->getLine() . ";message:" . $e->getMessage()); self::$static_error = $e->getMessage(); return false; } } /** * @desc:授权 * @Author: hua * @Date: 2021/10/25 * @Time: 11:21 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false */ public static function checkIsAuthorized($params) { try { $where = [['mall_id' => $params['mall_id']], ['status' => [StatusEnum::ENABLED, StatusEnum::DISABLED]]]; if (!empty($params["openid"])) { $where[] = ['openid' => $params["openid"]]; } else if (!empty($params["unionid"])) { $where[] = ['unionid' => $params["unionid"]]; } if (!empty($params["platform"])) $where[] = ['platform' => $params["platform"]]; $user_info = UserInfo::getOne($where); \Yii::info('授权参数:'.json_encode($params)); $user = User::findOne(['id' => $user_info->user_id]); if (empty($user_info) || empty($user_info->user_id) || ($user && empty($user->mobile))) { // 将旧的openid删除 $other_where = $where = ['mall_id' => $params['mall_id'], 'unionid' => $params["unionid"], 'status' => StatusEnum::ENABLED]; if (!empty($params["platform"])) $where['platform'] =$params["platform"]; if (!empty($params["openid"])) $where['openid'] =$params["openid"]; UserInfo::updateAll(['status' => StatusEnum::DELETE],$where); $params['user_id'] = 0; //小鹅通特殊操作 if (!empty($user_info->user_id)) { $params['user_id'] = $user_info->user_id; } $res = UserInfo::setData($params); if ($res === false) throw new Exception('授权失败'); if(!empty($params["unionid"])){ $other_platform = UserInfo::find()->where($other_where)->one();// 通过unionid获取其他渠道的user_id if ($other_platform && $other_platform->user_id) { $user = User::findOne($other_platform->user_id); if ($user && !empty($user->mobile)) { if(!empty($params['share_user_id'])&&empty($user->parent_id)){ $user->temp_parent_id = $params['share_user_id']; } $user->last_login_at = time(); $user->save(); // 将当前渠道的user_info字段填充 $res->user_id = $other_platform->user_id; if (!$res->save()) \Yii::error("user-info保存失败:" . $res->getErrorMessage()); return ['user' => $user]; } } } return ['user' => null]; } else { //之前获取不到微信昵称和头像则更新用户昵称和头像 $user = User::findOne($user_info->user_id); if ($user) { if($user['status']==0) throw new \Exception('账号已注销'); // if ($user->nickname == "微信用户") { // $user->nickname = isset($params["nickname"]) ? (string)$params["nickname"] : ""; // $user->avatar_url = isset($params["headimgurl"]) ? $params["headimgurl"] : ""; // } if(!empty($params['share_user_id'])&&empty($user->parent_id)){ $user->temp_parent_id = $params['share_user_id']; } $user->last_login_at = time(); $user->save(); } if (empty($user_info->unionid) && !empty($params['unionid'])) { $user_info->unionid = $params['unionid']; $user_info->save(); } return ['user' => $user]; } } catch (\Exception $e) { \Yii::error("error=" . $e->getFile() . ";line:" . $e->getLine() . ";message:" . $e->getMessage()); self::$static_error = $e->getMessage(); return false; } } /** * @desc:授权手机号码,同时登录 * @Author: hua * @Date: 2021/10/25 * @Time: 11:51 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false */ public function authorizedMobilePhone($params) { // $t = \Yii::$app->db->beginTransaction(); try { $wechatModel = \Yii::$app->wechat; $resultData = $wechatModel->miniProgram->auth->session($params['code']); $errmsg = $resultData['errmsg'] ?? ''; if($errmsg){ \Yii::error('auth session error:'.json_encode($resultData)); throw new Exception($errmsg); } $sessionKey = $resultData["session_key"]; $openid = $resultData["openid"]; $iv = $params['iv']; $encrypted = $params['encryptedData']; $data = $wechatModel->miniProgram->encryptor->decryptData($sessionKey, $iv, $encrypted); \Yii::info('授权手机号返回信息:'.json_encode($data)); $params['area_code'] = $data["countryCode"];// 区号 $params['mobile'] = $data["purePhoneNumber"];// 不带区号的手机号码 $where = [['mobile' => $params['mobile']], ['mall_id' => $params['mall_id']], ['status' => [StatusEnum::DISABLED, StatusEnum::ENABLED]]]; $user = User::getOne($where); $user_info = UserInfo::findOne(['mall_id' => $params['mall_id'], 'openid' => $openid,'status'=>StatusEnum::ENABLED]); $platform_data = json_decode($user_info->platform_data, true); if (!empty($user)) { $res = UserInfo::findOne(['mall_id' => $params['mall_id'], 'user_id' => $user->id,'platform'=>$user_info->platform,'status'=>StatusEnum::ENABLED]); if (!empty($res)) throw new Exception('该手机号码已经被注册'); $user_info->user_id = $user->id; if (empty($user_info->unionid) && !empty($params['unionid'])) { $user_info->unionid = $params['unionid']; } $res = $user_info->save(); if ($res == false) throw new Exception(UserInfo::getStaticError()); $user->nickname = (string)$platform_data['nickName']; $user->avatar_url = $platform_data['avatarUrl']; $user->platform = $user_info->platform; $res = $user->save(); if ($res == false) throw new Exception(User::getStaticError()); } else { //小鹅通特殊操作 if ($user_info && $user_info->user_id) { $params['id'] = $user_info->user_id; $user = User::getOne([['id' => $user_info->user_id], ['status' => [StatusEnum::DISABLED, StatusEnum::ENABLED]]]); if ($user && $user->parent_id) { $params['parent_id'] = $user->parent_id; } } $password = substr($params['mobile'],-6,6); $params['password'] = \Yii::$app->getSecurity()->generatePasswordHash($password); $params["username"] = $params["mobile"]; $params["openid"] = $platform_data["openid"]; $params["unionid"] = $platform_data["unionid"] ?? ''; $params["nickname"] = (string)$platform_data["nickName"]; $params["headimgurl"] = $platform_data["avatarUrl"]; $params["avatar_url"] = $platform_data["avatarUrl"]; $params['platform'] = $user_info->platform; $params['last_login_at'] = time(); $user = User::setData($params); if ($user == false) throw new Exception(User::getStaticError()); // 小程序授权手机触发注册事件 $event = new UserRegisterEvent($params['mall_id']); $data = ['user_id' => $user->id, 'platform' => $user->platform]; \Yii::$app->services->events->dispatch($event, $data, $event->listeners); $user_info->user_id = $user->id; $res = $user_info->save(); if ($res == false) throw new Exception(UserInfo::getStaticError()); } // $t->commit(); \Yii::$app->user->login($user); // 触发登录成功事件,事务提交完成后触发 $event = new UserLoginEvent($user->mall_id); \Yii::$app->services->events->dispatch($event, [ 'mall_id' => $user->mall_id, 'nickname' => $user->nickname, 'user_id' => $user->id, 'platform' => $user->platform, 'ip' => ArrayHelper::get_client_ip(), 'device_type' => $params['device_type'] ?? '', 'device_mac' => $params['device_mac'] ?? '', ], $event->listeners); return \Yii::$app->services->apiAccessToken->getAccessToken($user, 'api'); } catch (\Exception $e) { // $t->rollBack(); self::$static_error = $e->getMessage(); \Yii::error('绑定手机号错误:' . $e->getFile().',第'.$e->getLine().'行,原因:'.$e->getMessage()); return false; } } /** * @desc:微信小程序授权,不登录,等授权手机号码再登录 * @Author: hua * @Date: 2021/10/25 * @Time: 11:50 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false */ public function miniAuthorized($params) { try { $wechatModel = \Yii::$app->wechat; //微信小程序授权登录 $result_data = $wechatModel->miniProgram->auth->session($params['code']); if (isset($result_data["errcode"]) && $result_data["errcode"] != 0) throw new Exception($result_data["errmsg"]); //授权成功获取sessiong_key $session_key = $result_data["session_key"]; $iv = $params['iv']; $encrypted = $params['encryptedData']; //解密微信加密数据 $data = $wechatModel->miniProgram->encryptor->decryptData($session_key, $iv, $encrypted); $openid = isset($data["openId"]) ? $data["openId"] : (isset($result_data["openid"]) ? $result_data["openid"] : ""); if (empty($openid)) throw new Exception('缺少openid参数'); $params["openid"] = $result_data["openid"]; $params["unionid"] = $result_data["unionid"] ?? ''; $params["nickname"] = $data["nickName"]; $params["headimgurl"] = $data["avatarUrl"]; $params["session_key"] = $session_key; $params['platform'] = User::PLATFORM_MP_WX; $params['platform_data'] = $data; $result = self::checkIsAuthorized($params); $return_data['openid'] = $result_data["openid"]; if (empty($result)) throw new Exception(self::getStaticError()); if (!empty($result['user'])) { $user = $result['user']; \Yii::$app->user->login($user); $res = \Yii::$app->services->apiAccessToken->getAccessToken($user, 'api'); $return_data['access_token'] = $res['access_token']; // 触发登录成功事件,事务提交完成后触发 $event = new UserLoginEvent($user['mall_id']); \Yii::$app->services->events->dispatch($event, [ 'mall_id' => $user['mall_id'], 'nickname' => $user['nickname'], 'user_id' => $user['id'], 'platform' => $user['platform'], 'ip' => ArrayHelper::get_client_ip(), 'device_type' => $params['device_type'] ?? '', 'device_mac' => $params['device_mac'] ?? '', ], $event->listeners); } return $return_data; } catch (\Exception $e) { \Yii::error("miniAuthorized error=" . $e->getFile() . ";line:" . $e->getLine() . ";message:" . $e->getMessage()); self::$static_error = $e->getMessage(); return false; } } /** * @desc:微信授权,不登录,等关联手机号再进行登录 * @Author: hua * @Date: 2021/10/22 * @Time: 11:38 * @Copyright: copyright (c) 2021 广东七件事集团 * @param $params * @return array|false */ public function authorized($params) { try { $return_data['access_token'] = ''; $wechatModel = \Yii::$app->wechat; if (!$wechatModel->isWechat) throw new Exception('不是微信请求'); $result = $wechatModel->app->oauth->user(); if (!empty($result)) { $user_info = $result->original; $params["openid"] = $user_info["openid"]; $params["nickname"] = $user_info["nickname"]; $params["headimgurl"] = $user_info["headimgurl"]; $params["unionid"] = $user_info["unionid"] ?? ''; $params['platform'] = User::PLATFORM_WECHAT; $params['platform_data'] = $user_info; $result = self::checkIsAuthorized($params); $return_data['openid'] = $user_info["openid"]; if (empty($result)) throw new Exception(self::getStaticError()); if (!empty($result['user'])) { $user = $result['user']; \Yii::$app->user->login($user); $res = \Yii::$app->services->apiAccessToken->getAccessToken($user, 'api'); $return_data['access_token'] = $res['access_token']; // 触发登录成功事件,事务提交完成后触发 $event = new UserLoginEvent($user['mall_id']); \Yii::$app->services->events->dispatch($event, [ 'mall_id' => $user['mall_id'], 'nickname' => $user['nickname'], 'user_id' => $user['id'], 'platform' => $user['platform'], 'ip' => ArrayHelper::get_client_ip(), 'device_type' => $params['device_type'] ?? '', 'device_mac' => $params['device_mac'] ?? '', ], $event->listeners); } return $return_data; } return $return_data; } catch (\Exception $e) { \Yii::error("authorized error=" . $e->getFile() . ";line:" . $e->getLine() . ";message:" . $e->getMessage()); self::$static_error = $e->getMessage(); return false; } } /** * @desc: * @Author: hua * @Date: 2021/10/25 * @Time: 16:40 * @Copyright: copyright (c) 2021 广东七件事集团 * @return array * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException * @throws \Psr\SimpleCache\InvalidArgumentException */ public function getJsSdkConfig() { $app = \Yii::$app->wechat->getApp(); $url = \Yii::$app->request->get('url'); if ($url) { $app->jssdk->setUrl($url); } $res = $app->jssdk->buildConfig([ 'chooseImage', 'onMenuShareTimeline', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone', 'updateAppMessageShareData', 'stopRecord', 'scanQRCode', 'chooseWXPay', 'getLocation', 'updateTimelineShareData' ], $debug = false, $beta = false, $json = false); return ['config' => $res]; } }