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
101 lines
2.9 KiB
<?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;
|
|
}
|
|
}
|