feat: [users] 재직상태(재직/휴직/퇴직) 표시 및 수정 기능 추가

- 사용자 목록 테이블에 재직상태 컬럼 추가 (재직/휴직/퇴직 배지)
- 사용자 수정 화면에 재직상태 select 필드 추가
- UserService.getUsers()에 employee_status 서브쿼리 추가
- UserService.updateUser()에서 tenant_user_profiles에 employee_status 저장
- UpdateUserRequest에 employee_status validation 추가
This commit is contained in:
김보곤
2026-02-28 08:23:16 +09:00
parent 0b5429838c
commit 8ba619d659
5 changed files with 42 additions and 5 deletions

View File

@@ -91,7 +91,7 @@ public function edit(int $id): View
? DB::table('tenant_user_profiles')
->where('tenant_id', $tenantId)
->where('user_id', $user->id)
->first(['position_key', 'job_title_key'])
->first(['position_key', 'job_title_key', 'employee_status'])
: null;
return view('users.edit', compact('user', 'roles', 'departments', 'userRoleIds', 'userDepartmentIds',

View File

@@ -70,6 +70,7 @@ public function rules(): array
'department_ids.*' => 'integer|exists:departments,id',
'position_key' => 'nullable|string|max:64',
'job_title_key' => 'nullable|string|max:64',
'employee_status' => 'nullable|in:active,leave,resigned',
];
}

View File

@@ -23,7 +23,7 @@ public function __construct(
public function getUsers(array $filters = [], int $perPage = 15): LengthAwarePaginator
{
$tenantId = session('selected_tenant_id');
$query = User::query()->withTrashed();
$query = User::query()->select('users.*')->withTrashed();
// 슈퍼관리자 보호: 일반관리자는 슈퍼관리자를 볼 수 없음
if (! auth()->user()?->is_super_admin) {
@@ -37,6 +37,14 @@ public function getUsers(array $filters = [], int $perPage = 15): LengthAwarePag
'departmentUsers' => fn ($q) => $q->where('tenant_id', $tenantId)->with('department'),
'tenants',
]);
// 재직상태 서브쿼리
$query->addSelect(['employee_status' => DB::table('tenant_user_profiles')
->select('employee_status')
->whereColumn('user_id', 'users.id')
->where('tenant_id', $tenantId)
->limit(1),
]);
} else {
$query->with(['tenants']);
}
@@ -248,7 +256,7 @@ public function updateUser(int $id, array $data): bool
$this->syncDepartments($user, $tenantId, $departmentIds);
}
// position_key, job_title_key → tenant_user_profiles 저장
// position_key, job_title_key, employee_status → tenant_user_profiles 저장
if ($tenantId) {
$profileFields = [];
if (array_key_exists('position_key', $data)) {
@@ -257,6 +265,9 @@ public function updateUser(int $id, array $data): bool
if (array_key_exists('job_title_key', $data)) {
$profileFields['job_title_key'] = $data['job_title_key'] ?: null;
}
if (array_key_exists('employee_status', $data)) {
$profileFields['employee_status'] = $data['employee_status'] ?: 'active';
}
if (! empty($profileFields)) {
DB::table('tenant_user_profiles')->updateOrInsert(
['tenant_id' => $tenantId, 'user_id' => $id],
@@ -266,7 +277,7 @@ public function updateUser(int $id, array $data): bool
}
// role_ids, department_ids, position/job_title은 User 모델의 fillable이 아니므로 제거
unset($data['role_ids'], $data['department_ids'], $data['position_key'], $data['job_title_key']);
unset($data['role_ids'], $data['department_ids'], $data['position_key'], $data['job_title_key'], $data['employee_status']);
return $user->update($data);
}

View File

@@ -137,6 +137,20 @@ class="px-3 py-2 bg-gray-100 hover:bg-gray-200 text-gray-600 rounded-lg transiti
@include('hr.employees.partials.position-add-modal')
<!-- 재직상태 -->
<div class="mb-8">
<h2 class="text-lg font-semibold text-gray-800 mb-4 pb-2 border-b">재직상태</h2>
<div style="max-width: 300px;">
<select name="employee_status"
class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
@php $empStatus = $profile?->employee_status ?? 'active'; @endphp
<option value="active" {{ $empStatus === 'active' ? 'selected' : '' }}>재직</option>
<option value="leave" {{ $empStatus === 'leave' ? 'selected' : '' }}>휴직</option>
<option value="resigned" {{ $empStatus === 'resigned' ? 'selected' : '' }}>퇴직</option>
</select>
</div>
</div>
<!-- 비밀번호 초기화 -->
<div class="mb-8">
<h2 class="text-lg font-semibold text-gray-800 mb-4 pb-2 border-b">비밀번호</h2>

View File

@@ -9,6 +9,7 @@
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">이메일</th>
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">부서</th>
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">역할</th>
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">재직</th>
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">상태</th>
<th class="px-6 py-3 text-left text-sm font-semibold text-gray-700 uppercase tracking-wider">작업</th>
</tr>
@@ -80,6 +81,16 @@
<span class="text-gray-400">-</span>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap">
@php $empStatus = $user->employee_status ?? 'active'; @endphp
@if($empStatus === 'active')
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-blue-800">재직</span>
@elseif($empStatus === 'leave')
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-yellow-800">휴직</span>
@else
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">퇴직</span>
@endif
</td>
<td class="px-6 py-4 whitespace-nowrap">
@if($user->is_active)
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">
@@ -136,7 +147,7 @@ class="text-blue-600 hover:text-blue-900 mr-3">
</tr>
@empty
<tr>
<td colspan="8" class="px-6 py-4 text-center text-gray-500">
<td colspan="9" class="px-6 py-4 text-center text-gray-500">
사용자가 없습니다.
</td>
</tr>