69 lines
2.8 KiB
PHP
69 lines
2.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace app\api\controller;
|
|
|
|
use app\api\logic\tcm\TangDetectiveLogic;
|
|
use app\common\service\game\TangDetectiveProgress;
|
|
use app\common\service\game\TangDetectiveProgressException;
|
|
use think\facade\Log;
|
|
|
|
/** All actions use the existing LoginMiddleware token identity. */
|
|
class TangDetectiveController extends BaseApiController
|
|
{
|
|
public array $notNeedLogin = [];
|
|
|
|
public function catalog()
|
|
{
|
|
return $this->respond('GET', static fn (): array => (new TangDetectiveProgress())->catalog());
|
|
}
|
|
|
|
public function progress()
|
|
{
|
|
return $this->respond('GET', fn (): array => (new TangDetectiveLogic())->read((int) $this->userId));
|
|
}
|
|
|
|
public function saveProgress()
|
|
{
|
|
return $this->respond('POST', function (): array {
|
|
if (strtolower($this->request->contentType()) !== 'application/json') {
|
|
throw new TangDetectiveProgressException('UNSUPPORTED_MEDIA_TYPE', '请使用 JSON 提交存档');
|
|
}
|
|
$policy = new TangDetectiveProgress();
|
|
$request = $policy->decodeRequest((string) $this->request->getContent());
|
|
return (new TangDetectiveLogic($policy))->save((int) $this->userId, $request);
|
|
});
|
|
}
|
|
|
|
private function respond(string $method, callable $action)
|
|
{
|
|
try {
|
|
// Guard methods too: ThinkPHP's conventional controller routes remain enabled.
|
|
if (($method === 'GET' && !$this->request->isGet())
|
|
|| ($method === 'POST' && !$this->request->isPost())) {
|
|
throw new TangDetectiveProgressException('METHOD_NOT_ALLOWED', '请求方式不正确');
|
|
}
|
|
if ($this->userId <= 0) {
|
|
throw new TangDetectiveProgressException('AUTH_REQUIRED', '请先登录');
|
|
}
|
|
return $this->data($action())->header(['Cache-Control' => 'no-store']);
|
|
} catch (TangDetectiveProgressException $exception) {
|
|
return $this->fail($exception->getMessage(), ['error_code' => $exception->errorCode()], 0, 0)
|
|
->header(['Cache-Control' => 'no-store']);
|
|
} catch (\Throwable $exception) {
|
|
try {
|
|
Log::warning('tang_detective_request_failure', [
|
|
'user_id' => $this->userId,
|
|
'error_code' => 'STORAGE_UNAVAILABLE',
|
|
'exception_class' => get_class($exception),
|
|
]);
|
|
} catch (\Throwable $loggingException) {
|
|
// No raw exception, request body, token or SQL is exposed on failure.
|
|
}
|
|
return $this->fail('云端存档暂时不可用,本机进度仍可保留', ['error_code' => 'STORAGE_UNAVAILABLE'], 0, 0)
|
|
->header(['Cache-Control' => 'no-store']);
|
|
}
|
|
}
|
|
}
|