find(); if ($player) { $hashed = $this->hashPassword($password); if ($player->password !== $hashed) { throw new ApiException('密码错误'); } $currentCoin = (float) $player->coin; $player->coin = $currentCoin + $coin; $player->save(); } else { $player = new DicePlayer(); $player->username = $username; $player->phone = $username; $player->password = $this->hashPassword($password); $player->status = self::STATUS_NORMAL; $player->coin = $coin; $player->save(); } $exp = (int) config('api.session_expire', 604800); $tokenResult = JwtToken::generateToken([ 'id' => (int) $player->id, 'username' => $username, 'plat' => 'api_login', 'access_exp' => $exp, ]); $token = $tokenResult['access_token']; UserCache::setSessionByUsername($username, $token); $userArr = $player->hidden(['password'])->toArray(); UserCache::setUser((int) $player->id, $userArr); $baseUrl = rtrim(config('api.login_url_base', 'https://127.0.0.1:6777'), '/'); $lang = in_array($lang, ['chs', 'en'], true) ? $lang : 'chs'; $tokenInUrl = str_replace('%3D', '=', urlencode($token)); $url = $baseUrl . '?token=' . $tokenInUrl . '&lang=' . $lang; return [ 'url' => $url, 'token' => $token, 'lang' => $lang, 'user_id' => (int) $player->id, 'user' => $userArr, ]; } /** * 从 JWT 中解析 username(仅解码 payload,不校验签名与过期,用于退出时清除会话) */ public static function getUsernameFromJwtPayload(string $token): ?string { $parts = explode('.', $token); if (count($parts) !== 3) { return null; } $payload = base64_decode(strtr($parts[1], '-_', '+/'), true); if ($payload === false) { return null; } $data = json_decode($payload, true); if (!is_array($data)) { return null; } $extend = $data['extend'] ?? $data; $username = $extend['username'] ?? null; return $username !== null ? trim((string) $username) : null; } /** * 从 Redis 获取用户信息(key = base64(user_id)),未命中则查 DicePlayer 并回写缓存 */ public static function getCachedUser(int $userId): array { $cached = UserCache::getUser($userId); if (!empty($cached)) { return $cached; } $user = DicePlayer::find($userId); if (!$user) { return []; } $arr = $user->hidden(['password'])->toArray(); UserCache::setUser($userId, $arr); return $arr; } }