You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.9 KiB

2 days ago
<?php
namespace App\Services\Sstbc;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use RuntimeException;
class SstbcApiClient
{
protected function baseUrl(): string
{
return rtrim((string) config('sstbc.base_url'), '/');
}
protected function timeout(): int
{
return max(5, (int) config('sstbc.http_timeout_seconds', 30));
}
public function getAccessToken(bool $forceRefresh = false): string
{
$cacheKey = 'sstbc_api_access_token';
if ($forceRefresh) {
Cache::forget($cacheKey);
}
return (string) Cache::remember($cacheKey, now()->addHours(23), function () {
$username = (string) config('sstbc.username');
$password = (string) config('sstbc.password');
if ($username === '' || $password === '') {
throw new RuntimeException('SSTBC API 账号未配置,请在 .env 中设置 SSTBC_API_USERNAME / SSTBC_API_PASSWORD');
}
$response = Http::timeout($this->timeout())
->acceptJson()
->post($this->baseUrl().'/api/admin/auth/login', [
'username' => $username,
'password' => $password,
]);
if (! $response->successful()) {
throw new RuntimeException('SSTBC 登录失败:'.$response->body());
}
$token = (string) ($response->json('access_token') ?? '');
if ($token === '') {
throw new RuntimeException('SSTBC 登录响应缺少 access_token');
}
return $token;
});
}
/**
* @param array<string, mixed> $params
* @return array<string, mixed>
*/
public function fetchCourses(array $params = []): array
{
return $this->requestCourses($params, false);
}
/**
* @param array<string, mixed> $params
* @return array<string, mixed>
*/
protected function requestCourses(array $params, bool $retried): array
{
$token = $this->getAccessToken($retried);
$query = array_merge([
'page' => 1,
'page_size' => 10,
'sort_name' => 'start_date',
'sort_type' => 'DESC',
'show_relation' => ['type_detail'],
], $params);
$response = Http::timeout($this->timeout())
->acceptJson()
->withToken($token)
->get($this->baseUrl().'/api/admin/courses/index', $query);
if ($response->status() === 401 && ! $retried) {
return $this->requestCourses($params, true);
}
if (! $response->successful()) {
throw new RuntimeException('SSTBC 课程列表请求失败:'.$response->body());
}
/** @var array<string, mixed> $body */
$body = $response->json() ?? [];
return $body;
}
}