This commit is contained in:
大哥大哥的大哥哥
2026-09-09 14:47:29 +08:00
parent 4d9da40abd
commit 65755c9e96
832 changed files with 412085 additions and 0 deletions
@@ -0,0 +1,68 @@
<?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']);
}
}
}