feat: [payroll] 급여관리 페이지 접근 제한 (이름 기반)
- 허용 사용자: 이경호, 전진선, 김보곤 - 웹 컨트롤러: 미허용 시 안내 뷰 반환 - API 컨트롤러: 모든 엔드포인트에 403 반환 - restricted.blade.php 안내 페이지 생성
This commit is contained in:
@@ -12,15 +12,33 @@
|
||||
|
||||
class PayrollController extends Controller
|
||||
{
|
||||
private const ALLOWED_PAYROLL_USERS = ['이경호', '전진선', '김보곤'];
|
||||
|
||||
public function __construct(
|
||||
private PayrollService $payrollService
|
||||
) {}
|
||||
|
||||
private function checkPayrollAccess(): ?JsonResponse
|
||||
{
|
||||
if (! in_array(auth()->user()->name, self::ALLOWED_PAYROLL_USERS)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '급여관리는 관계자만 볼 수 있습니다.',
|
||||
], 403);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 급여 목록 조회 (HTMX → HTML / 일반 → JSON)
|
||||
*/
|
||||
public function index(Request $request): JsonResponse|Response
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$payrolls = $this->payrollService->getPayrolls(
|
||||
$request->all(),
|
||||
$request->integer('per_page', 20)
|
||||
@@ -47,6 +65,10 @@ public function index(Request $request): JsonResponse|Response
|
||||
*/
|
||||
public function stats(Request $request): JsonResponse|Response
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$stats = $this->payrollService->getMonthlyStats(
|
||||
$request->integer('year') ?: null,
|
||||
$request->integer('month') ?: null
|
||||
@@ -67,6 +89,10 @@ public function stats(Request $request): JsonResponse|Response
|
||||
*/
|
||||
public function store(Request $request): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'user_id' => 'required|integer|exists:users,id',
|
||||
'pay_year' => 'required|integer|min:2020|max:2100',
|
||||
@@ -124,6 +150,10 @@ public function store(Request $request): JsonResponse
|
||||
*/
|
||||
public function update(Request $request, int $id): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'base_salary' => 'sometimes|required|numeric|min:0',
|
||||
'overtime_pay' => 'nullable|numeric|min:0',
|
||||
@@ -175,6 +205,10 @@ public function update(Request $request, int $id): JsonResponse
|
||||
*/
|
||||
public function destroy(Request $request, int $id): JsonResponse|Response
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
try {
|
||||
$result = $this->payrollService->deletePayroll($id);
|
||||
|
||||
@@ -214,6 +248,10 @@ public function destroy(Request $request, int $id): JsonResponse|Response
|
||||
*/
|
||||
public function confirm(Request $request, int $id): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
try {
|
||||
$payroll = $this->payrollService->confirmPayroll($id);
|
||||
|
||||
@@ -245,6 +283,10 @@ public function confirm(Request $request, int $id): JsonResponse
|
||||
*/
|
||||
public function pay(Request $request, int $id): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
try {
|
||||
$payroll = $this->payrollService->payPayroll($id);
|
||||
|
||||
@@ -276,6 +318,10 @@ public function pay(Request $request, int $id): JsonResponse
|
||||
*/
|
||||
public function copyFromPrevious(Request $request): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'pay_year' => 'required|integer|min:2020|max:2100',
|
||||
'pay_month' => 'required|integer|min:1|max:12',
|
||||
@@ -315,6 +361,10 @@ public function copyFromPrevious(Request $request): JsonResponse
|
||||
*/
|
||||
public function bulkGenerate(Request $request): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'year' => 'required|integer|min:2020|max:2100',
|
||||
'month' => 'required|integer|min:1|max:12',
|
||||
@@ -342,8 +392,12 @@ public function bulkGenerate(Request $request): JsonResponse
|
||||
/**
|
||||
* 엑셀(CSV) 내보내기
|
||||
*/
|
||||
public function export(Request $request): StreamedResponse
|
||||
public function export(Request $request): StreamedResponse|JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$payrolls = $this->payrollService->getExportData($request->all());
|
||||
$year = $request->input('year', now()->year);
|
||||
$month = $request->input('month', now()->month);
|
||||
@@ -392,6 +446,10 @@ public function export(Request $request): StreamedResponse
|
||||
*/
|
||||
public function settingsIndex(Request $request): JsonResponse|Response
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$settings = $this->payrollService->getSettings();
|
||||
|
||||
if ($request->header('HX-Request')) {
|
||||
@@ -409,6 +467,10 @@ public function settingsIndex(Request $request): JsonResponse|Response
|
||||
*/
|
||||
public function settingsUpdate(Request $request): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'health_insurance_rate' => 'nullable|numeric|min:0|max:100',
|
||||
'long_term_care_rate' => 'nullable|numeric|min:0|max:100',
|
||||
@@ -444,6 +506,10 @@ public function settingsUpdate(Request $request): JsonResponse
|
||||
*/
|
||||
public function calculate(Request $request): JsonResponse
|
||||
{
|
||||
if ($denied = $this->checkPayrollAccess()) {
|
||||
return $denied;
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'base_salary' => 'required|numeric|min:0',
|
||||
'overtime_pay' => 'nullable|numeric|min:0',
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
class PayrollController extends Controller
|
||||
{
|
||||
private const ALLOWED_PAYROLL_USERS = ['이경호', '전진선', '김보곤'];
|
||||
|
||||
public function __construct(
|
||||
private PayrollService $payrollService
|
||||
) {}
|
||||
@@ -24,6 +26,10 @@ public function index(Request $request): View|Response
|
||||
return response('', 200)->header('HX-Redirect', route('hr.payrolls.index'));
|
||||
}
|
||||
|
||||
if (! in_array(auth()->user()->name, self::ALLOWED_PAYROLL_USERS)) {
|
||||
return view('hr.payrolls.restricted');
|
||||
}
|
||||
|
||||
$stats = $this->payrollService->getMonthlyStats();
|
||||
$departments = $this->payrollService->getDepartments();
|
||||
$employees = $this->payrollService->getActiveEmployees();
|
||||
|
||||
17
resources/views/hr/payrolls/restricted.blade.php
Normal file
17
resources/views/hr/payrolls/restricted.blade.php
Normal file
@@ -0,0 +1,17 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', '급여관리 - 접근 제한')
|
||||
|
||||
@section('content')
|
||||
<div class="flex items-center justify-center" style="min-height: 60vh;">
|
||||
<div class="text-center">
|
||||
<div class="text-gray-300 mb-6">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="mx-auto" style="width: 80px; height: 80px;" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="text-xl font-semibold text-gray-700 mb-2">접근이 제한된 페이지입니다</h2>
|
||||
<p class="text-gray-500">급여관리는 관계자만 볼 수 있습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user