find(); //用户表登录信息更新 $admin->login_time = $time; $admin->login_ip = request()->ip(); $admin->save(); //设置token $adminInfo = AdminTokenService::setToken($admin->id, $params['terminal'], $admin->multipoint_login); //返回登录信息 $avatar = $admin->avatar ? $admin->avatar : Config::get('project.default_image.admin_avatar'); $avatar = FileService::getFileUrl($avatar); return [ 'name' => $adminInfo['name'], 'avatar' => $avatar, 'role_name' => $adminInfo['role_name'], 'token' => $adminInfo['token'], 'is_paw' => $admin->is_paw ?? 1, // 0=需要修改密码,1=正常 ]; } /** * @notes 企业微信授权登录 */ public function workWechatLogin($params) { $code = $params['code']; $terminal = $params['terminal'] ?? 1; $corpId = env('work_wechat.corp_id', ''); $secret = env('work_wechat.secret', ''); if (empty($corpId) || empty($secret)) { self::setError('企业微信未配置'); return false; } // 获取 access_token $accessToken = self::getWorkWechatAccessToken($corpId, $secret); if (!$accessToken) { return false; } // 用 code 换取用户身份 $url = "https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token={$accessToken}&code={$code}"; $response = self::httpGet($url); if (!$response || $response['errcode'] != 0) { $errMsg = $response['errmsg'] ?? '未知错误'; Log::error('企业微信获取用户身份失败: ' . $errMsg); self::setError('企业微信授权失败: ' . $errMsg); return false; } $wxUserId = $response['userid'] ?? ''; if (empty($wxUserId)) { self::setError('未获取到企业微信用户身份,可能是外部联系人'); return false; } // 通过 work_wechat_userid 匹配管理员(SoftDelete trait 自动排除已删除记录) $admin = Admin::where('work_wechat_userid', '=', $wxUserId)->find(); if (!$admin) { self::setError('该企业微信账号未绑定管理员,请联系管理员绑定(UserId: ' . $wxUserId . ')'); return false; } if ($admin->disable === 1) { self::setError('账号已被禁用'); return false; } // 更新登录信息 $time = time(); $admin->login_time = $time; $admin->login_ip = request()->ip(); $admin->save(); // 设置 token $adminInfo = AdminTokenService::setToken($admin->id, $terminal, $admin->multipoint_login); $avatar = $admin->avatar ?: Config::get('project.default_image.admin_avatar'); $avatar = FileService::getFileUrl($avatar); return [ 'name' => $adminInfo['name'], 'avatar' => $avatar, 'role_name' => $adminInfo['role_name'], 'token' => $adminInfo['token'], 'is_paw' => $admin->is_paw ?? 1, // 0=需要修改密码,1=正常 ]; } /** * @notes 获取企业微信 access_token(带缓存),供外部(如绑定流程)调用 */ public static function getWorkWechatAccessTokenStatic(string $corpId, string $secret) { return self::getWorkWechatAccessToken($corpId, $secret); } /** * @notes 获取企业微信 access_token(带缓存) */ private static function getWorkWechatAccessToken(string $corpId, string $secret) { $cacheKey = 'work_wechat_access_token_' . md5($corpId . $secret); $cached = Cache::get($cacheKey); if ($cached) { return $cached; } $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$corpId}&corpsecret={$secret}"; $response = self::httpGet($url); if (!$response || $response['errcode'] != 0) { $errMsg = $response['errmsg'] ?? '未知错误'; Log::error('获取企业微信access_token失败: ' . $errMsg); self::setError('获取企业微信凭证失败: ' . $errMsg); return false; } $accessToken = $response['access_token']; Cache::set($cacheKey, $accessToken, $response['expires_in'] - 200); return $accessToken; } /** * @notes HTTP GET 请求 */ private static function httpGet(string $url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_TIMEOUT, 10); $result = curl_exec($ch); curl_close($ch); if ($result === false) { return null; } return json_decode($result, true); } /** * @notes 退出登录 * @param $adminInfo * @return bool * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author 令狐冲 * @date 2021/7/5 14:34 */ public function logout($adminInfo) { //token不存在,不注销 if (!isset($adminInfo['token'])) { return false; } //设置token过期 return AdminTokenService::expireToken($adminInfo['token']); } /** * @notes 首次登录修改密码 * @param string $token * @param string $password * @return bool */ public function changeFirstPassword($token, $password) { try { // 通过 token 获取管理员信息 $adminSession = \app\common\model\auth\AdminSession::where('token', '=', $token) ->where('expire_time', '>', time()) ->find(); if (!$adminSession) { self::setError('登录已过期,请重新登录'); return false; } $admin = Admin::find($adminSession->admin_id); if (!$admin) { self::setError('管理员不存在'); return false; } // 使用系统的密码加密方式 $passwordSalt = Config::get('project.unique_identification'); $encryptedPassword = create_password($password, $passwordSalt); // 更新密码和 is_paw 标记 $admin->password = $encryptedPassword; $admin->is_paw = 1; $admin->save(); // 使当前 token 过期,要求重新登录 AdminTokenService::expireToken($token); return true; } catch (\Exception $e) { self::setError($e->getMessage()); return false; } } }