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.
99 lines
3.1 KiB
99 lines
3.1 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Admin;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Competition;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Validation\ValidationException;
|
|
|
|
class CompetitionLogoController extends Controller
|
|
{
|
|
public function store(Request $request, Competition $competition): JsonResponse
|
|
{
|
|
$request->validate([
|
|
'file' => ['required', 'file', 'max:2048', 'mimes:png,jpg,jpeg,webp,gif,svg'],
|
|
]);
|
|
|
|
$uploaded = $request->file('file');
|
|
$ext = strtolower((string) ($uploaded->getClientOriginalExtension() ?: $uploaded->extension() ?: 'png'));
|
|
$dir = 'competitions/'.$competition->id;
|
|
$filename = 'logo-'.bin2hex(random_bytes(4)).'.'.$ext;
|
|
|
|
$this->deleteStoredLogos($competition);
|
|
|
|
try {
|
|
$path = $uploaded->storeAs($dir, $filename, 'public');
|
|
} catch (\Throwable $e) {
|
|
Log::error('competition.logo.store_exception', [
|
|
'competition_id' => $competition->id,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
|
|
throw ValidationException::withMessages([
|
|
'file' => ['Logo 保存失败,请稍后重试'],
|
|
]);
|
|
}
|
|
|
|
if (! is_string($path) || $path === '' || $path === '0' || ! Storage::disk('public')->exists($path)) {
|
|
throw ValidationException::withMessages([
|
|
'file' => ['Logo 保存失败,请稍后重试'],
|
|
]);
|
|
}
|
|
|
|
$url = '/storage/'.$path.'?t='.time();
|
|
$this->writeLogoUrl($competition, $url);
|
|
|
|
return response()->json([
|
|
'url' => $url,
|
|
'logoUrl' => $url,
|
|
]);
|
|
}
|
|
|
|
public function destroy(Competition $competition): JsonResponse
|
|
{
|
|
$this->deleteStoredLogos($competition);
|
|
$this->writeLogoUrl($competition, '');
|
|
|
|
return response()->json([
|
|
'url' => '',
|
|
'logoUrl' => '',
|
|
]);
|
|
}
|
|
|
|
private function writeLogoUrl(Competition $competition, string $url): void
|
|
{
|
|
$branding = is_array($competition->branding_json) ? $competition->branding_json : [];
|
|
$login = is_array($branding['login'] ?? null) ? $branding['login'] : [];
|
|
if ($url === '') {
|
|
unset($login['logoUrl']);
|
|
} else {
|
|
$login['logoUrl'] = $url;
|
|
}
|
|
if ($login === []) {
|
|
unset($branding['login']);
|
|
} else {
|
|
$branding['login'] = $login;
|
|
}
|
|
$competition->branding_json = $branding === [] ? null : $branding;
|
|
$competition->save();
|
|
}
|
|
|
|
private function deleteStoredLogos(Competition $competition): void
|
|
{
|
|
$dir = 'competitions/'.$competition->id;
|
|
$disk = Storage::disk('public');
|
|
if (! $disk->exists($dir)) {
|
|
return;
|
|
}
|
|
foreach ($disk->files($dir) as $file) {
|
|
if (str_starts_with(basename($file), 'logo')) {
|
|
$disk->delete($file);
|
|
}
|
|
}
|
|
}
|
|
}
|