repository = $repository; $this->source = $this->request->header('source'); $this->merId = $this->request->header('merId'); //点餐小程序 // $this->appid = 'wx10669a2eca032216'; // $this->secret = '0e71d5c636fdb9bf1c79c403db70f739'; // $this->appid = 'wx7b4d857deb0447f3'; // $this->secret = '643efbd7f3cd6398df1e7adb441afceb'; $this->appid = 'wx9082e5ac2fdb513f'; $this->secret = 'e334c41e1c4aa962f65d1882092fbda6'; } public function getUserUnionid(){ $data = $this->request->params(['code','source']); if(!$data['code'] || $data['code'] == '' || $data['code'] =='undefined') { return app('json')->fail("异常操作"); } // $appid = 'wx7b4d857deb0447f3'; // $secret = '643efbd7f3cd6398df1e7adb441afceb'; $appid = 'wx9082e5ac2fdb513f'; $secret = 'e334c41e1c4aa962f65d1882092fbda6'; $url = "https://api.weixin.qq.com/sns/jscode2session?appid=".$appid."&secret=".$secret."&js_code=".$data['code']."&grant_type=authorization_code"; $get = curlGet($url); if(!$get){ return app('json')->fail($url); } $get['cache_key'] = md5(time() . $data['code']); try { Cache::set('mp_code_' . $get['cache_key'], $get['session_key'], 86400); }catch (\Exception $exception) { Log::error($exception->getMessage()); } return app('json')->success($get); } /** * 小程序一键登录(合并 getUserUnionid + applet_phone) * 接收 code、encryptedData、iv,内部调用微信接口获取 session_key,解密手机号后注册/登录 * @param UserRepository $repository * @return \think\response\Json */ public function mpLogin(UserRepository $repository) { try { $data = $this->request->params(['code', 'encryptedData', 'iv', 'share_id', 'source']); if (!$data['code'] || $data['code'] == '' || $data['code'] == 'undefined') { return app('json')->fail('code参数缺失'); } if (!$data['encryptedData'] || $data['encryptedData'] == '') { return app('json')->fail('encryptedData参数缺失'); } if (!$data['iv'] || $data['iv'] == '') { return app('json')->fail('iv参数缺失'); } $appid = 'wx9082e5ac2fdb513f'; $secret = 'e334c41e1c4aa962f65d1882092fbda6'; // 1. 调用微信 jscode2session 接口获取 session_key 和 openid $url = "https://api.weixin.qq.com/sns/jscode2session?appid=" . $appid . "&secret=" . $secret . "&js_code=" . $data['code'] . "&grant_type=authorization_code"; $wxResult = curlGet($url); if (!$wxResult || !isset($wxResult['session_key'])) { Db::name('log')->insert(['data' => 'mpLogin jscode2session返回:' . json_encode($wxResult)]); Log::error('mpLogin jscode2session失败: ' . json_encode($wxResult)); return app('json')->fail('微信登录凭证校验失败'); } $sessionKey = $wxResult['session_key']; $openid = $wxResult['openid'] ?? ''; // 2. 解密手机号 $sessionKey = str_replace(' ', '+', $sessionKey); $encryptedData = str_replace(' ', '+', $data['encryptedData']); $iv = str_replace(' ', '+', $data['iv']); $pc = new WXBizDataCrypt($appid, $sessionKey); $errCode = $pc->decryptData($encryptedData, $iv, $decryptData); if ($errCode != 0) { Db::name('log')->insert(['data' => 'mpLogin手机号解密失败,errCode:' . $errCode . ',sessionKey:' . $sessionKey . ',encryptedData:' . $data['encryptedData'] . ',iv:' . $data['iv']]); return app('json')->fail('手机号解密失败'); } Db::name('log')->insert(['data' => 'mpLogin一键登录获取的数据:' . $decryptData]); $decryptData = json_decode($decryptData, true); $phone = $decryptData['purePhoneNumber'] ?? ''; if ($phone == '') { return app('json')->fail('未获取到手机号'); } if (!preg_match("/^1[3456789]{1}\d{9}$/", $phone) && !preg_match("/^[569]\d{7}$/", $phone)) { return app('json')->fail('手机号格式错误'); } // 3. 注册或登录 $userRes = Db::name('user')->where('account', $phone)->find(); $isnew = false; if (!$userRes) { $spreadUid = 0; if (!empty($data['share_id'])) { $spreadUid = Db::name('product_share')->where('id', $data['share_id'])->value('uid'); if (!intval($spreadUid)) { $spreadUid = 0; } } $repository->registr($phone, 123456, 'APP', '', '', '', $spreadUid); $isnew = true; } $user = $repository->accountByUser($phone); // 企业用户关联逻辑(与 Auth::applet_phone 保持一致) if ($this->source == 'yhc' && $this->merId) { $where = ['mer_id' => $this->merId, 'uid' => $user['uid']]; $count = Db::name('enterprise_user')->where($where)->count(); if ($count < 1) { $insert = ['mer_id' => $this->merId, 'uid' => $user['uid']]; $epData = $this->request->params(['spread', 'share_id']); if (isset($epData['spread']) && $epData['spread']) { $insert['puid'] = $epData['spread']; $insert['node_uid'] = $epData['spread']; } else if (isset($epData['share_id']) && $epData['share_id']) { $spreadUid = Db::name('product_share')->where('id', $epData['share_id'])->value('uid'); $insert['puid'] = $spreadUid; $insert['node_uid'] = $spreadUid; } if (!isset($insert['node_uid']) || !$insert['node_uid']) { return app('json')->fail('必须要有邀请人才能注册', ['is' => 1]); } if (isset($epData['spread']) && isset($zhuce)) { $insert['puid'] = $epData['spread']; $insert['node_uid'] = $epData['spread']; } Db::name('enterprise_user')->insert($insert); } } $user = $repository->mainUser($user); $tokenInfo = $repository->createToken($user); $repository->loginAfter($user); return app('json')->success(array_merge($repository->returnToken($user, $tokenInfo), [ 'is_new' => $isnew ? 1 : 0, 'openid' => $openid, ])); } catch (\Exception $e) { Db::name('log')->insert(['data' => 'mpLogin出错:' . $e->getFile() . ':' . $e->getLine() . '【' . $e->getMessage() . '】']); return app('json')->fail('登录失败'); } } public function getPhoneToBind(){ $data = $this->request->params([ 'cache_key', 'iv', 'encryptedData', 'third_user_id', 'source' ]); $session_key = Cache::get('mp_code_' . $data['cache_key']); $appid = $this -> appid; $secret = $this -> secret; if($data['source'] && $data['source'] == 'cxb'){ $appid = env('WECHAT_MP.APPID'); $secret = env('WECHAT_MP.SECRET'); } //解密获取用户信息urldecode $returnCode = $this -> decryptData($session_key,$data['encryptedData'],$data['iv'],$userInfo,$appid); if($returnCode != 0){ return app('json')->fail($returnCode); } $userInfo = json_decode($userInfo,true); if (!$userInfo || !isset($userInfo['purePhoneNumber'])) return app('json')->fail('手机号码获取失败'); $phone = $userInfo['purePhoneNumber']; $repository = app()->make(UserRepository::class); $user = $repository->thirdBinding($phone, false,'MP',$data['third_user_id'],1,"http://". $this->request->host(true));//2222 if($user){ $userRepository = app()->make(UserRepository::class); $userInfo1 = $userRepository->getOne(['uid' => $user['uid']]); //绑定线下充值金额 $unionUsersRepository = app()->make(UnionUsersRepository::class); $orderMerchantRepository = app()->make(OrderMerchantRepository::class); $notBind = $unionUsersRepository->getAllNotBind($data['third_user_id']); if ($notBind) { $orderMerchantRepository->doBindUser($userInfo1, 1); $userAccount = Db::name("UserAccount"); $userAccount -> insert(['type'=>1,'uid'=>$user['uid'],'nickname'=>$notBind['nickname'],'avater'=>$notBind['avatar']]); } $user = $repository->accountByUser($userInfo['purePhoneNumber']); $tokenInfo = $repository->createToken($user); $repository->loginAfter($user); return app('json')->success($repository->returnToken($user, $tokenInfo)); }else{ return app('json')->fail("绑定失败"); } } public function getUser(){ $data = $this->request->params(['unionid','nickname','avatar']); if(!$data['unionid'] || $data['unionid'] == '' || $data['unionid'] =='undefined'){ return app('json')->fail("异常操作"); } $repository = app()->make(UserRepository::class); $result = $repository ->wechatCheck($data['unionid']); if(isset($result['code']) && $result['code'] == 200){ //用户已注册并绑定了手机号码 $user = $repository->accountByUser($result['user']['account']); $tokenInfo = $repository->createToken($user); $repository->loginAfter($user); return app('json')->success($repository->returnToken($user, $tokenInfo)); } else{ try { if($data['avatar'] && $data['avatar'] != ''){ $data['avatar'] = str_replace('"', '', $data['avatar']); } Db::transaction(function () use ($data,$repository) { $unionData = [ 'unionid' => $data['unionid'], 'nickname' => $data['nickname'] ? : time(), 'avatar' => $data['avatar'] ? : 'https://cdn.bjtdba.com/vod/image/2025-01-21/20250121180855764.png', 'is_lock' => 1, 'lock_time' => date('Y-m-d H:i:s'), 'balance' => 0, 'give_money' => 0, 'pension' => 0, 'type' => 1, ]; $unionUsersDao = app()->make(UnionUsersDao::class); $unionUsersRepository = app()->make(UnionUsersRepository::class); $unionUser = $unionUsersRepository->getWhere(['unionid' => $data['unionid']]); if (!$unionUser) { $unionUsersDao->create($unionData); } else { $updateData = [ 'nickname' => $data['nickname'] ? : time(), 'avatar' => $data['avatar'] ? : 'https://cdn.bjtdba.com/vod/image/2025-01-21/20250121180855764.png', 'update_time' => date('Y-m-d H:i:s') ]; $unionUsersDao->update($unionUser->id, $updateData); } }); } catch (\Throwable $e) { Log::info($e->getMessage()); } } return app("json")->fail($result['msg']); } /** * 检验数据的真实性,并且获取解密后的明文. * @param $sessionKey string sessionKey * @param $encryptedData string 加密的用户数据 * @param $iv string 与用户数据一同返回的初始向量 * @param $data string 解密后的原文 * * @return int 成功0,失败返回对应的错误码 */ public function decryptData($sessionKey,$encryptedData, $iv, &$data, $appid) { if (strlen($sessionKey) != 24) { return -41001; } $aesKey=base64_decode($sessionKey); if (strlen($iv) != 24) { return -41002; } $aesIV=base64_decode($iv); $aesCipher=base64_decode($encryptedData); $result=openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); $dataObj=json_decode( $result ); if( $dataObj == NULL ) { return -41003; } if( $dataObj->watermark->appid != $appid ) { return -41003; } $data = $result; return 0; } }