giftcon_dev/app/Services/CsNoticeService.php
2026-02-09 19:47:58 +09:00

72 lines
2.1 KiB
PHP

<?php
namespace App\Services;
use App\Models\GcBoard;
use App\Repositories\Cs\NoticeRepository;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Session\Session;
use Illuminate\Support\Facades\Storage;
final class CsNoticeService
{
public function __construct(
private readonly NoticeRepository $repo,
) {}
public function paginate(string $q, int $perPage = 15): LengthAwarePaginator
{
// querystring 유지 (컨트롤러에서 request()->query() 붙일 필요 없음)
return $this->repo->paginate($q, $perPage)->withQueryString();
}
/**
* @return array{notice:GcBoard, prev:?GcBoard, next:?GcBoard}
*/
public function detail(int $seq, Session $session): array
{
$notice = $this->repo->findOrFail($seq);
// 조회수 (세션 기준 중복 방지)
$hitKey = "cs_notice_hit_{$seq}";
if (!$session->has($hitKey)) {
$this->repo->incrementHit($seq);
$session->put($hitKey, 1);
$notice->hit = (int)($notice->hit ?? 0) + 1; // 화면 즉시 반영용
}
$prev = $this->repo->findPrev($notice);
$next = $this->repo->findNext($notice);
return [
'notice' => $notice,
'prev' => $prev,
'next' => $next,
];
}
public function download(int $seq, int $slot): array
{
$notice = $this->repo->findOrFail($seq); // visibleNotice 보장
$file = $slot === 1
? (string)($notice->file_01 ?? '')
: (string)($notice->file_02 ?? '');
$file = trim($file);
if ($file === '') return ['ok' => false, 'path' => '', 'name' => ''];
// DB에 URL/경로가 섞여 있어도 파일명만 뽑아서 안전하게 처리
$name = basename(parse_url($file, PHP_URL_PATH) ?? $file);
$path = 'bbs/'.$name;
if (!Storage::disk('public')->exists($path)) {
return ['ok' => false, 'path' => '', 'name' => ''];
}
return ['ok' => true, 'path' => $path, 'name' => $name];
}
}