feat: [approvals] 결재선 에디터 2패널 UI/UX 개선
- 좌측 패널: 부서별 인원 목록 (접이식 그룹핑, 검색 필터) - 우측 패널: 결재선 (SortableJS 드래그앤드롭 순서 변경) - 부서별 전체 인원 API 추가 (GET /api/admin/tenant-users/list) - 결재/합의/참조 유형별 요약 바 추가 - position_key → positions 테이블 조인으로 직위 라벨 표시
This commit is contained in:
@@ -50,4 +50,80 @@ public function search(Request $request): JsonResponse
|
||||
'data' => $users,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 테넌트 전체 인원 목록 (부서별 그룹핑, 결재선 에디터용)
|
||||
*/
|
||||
public function list(): JsonResponse
|
||||
{
|
||||
$tenantId = session('selected_tenant_id');
|
||||
|
||||
$users = DB::table('users')
|
||||
->join('user_tenants', function ($join) use ($tenantId) {
|
||||
$join->on('users.id', '=', 'user_tenants.user_id')
|
||||
->where('user_tenants.tenant_id', $tenantId)
|
||||
->where('user_tenants.is_active', true);
|
||||
})
|
||||
->leftJoin('tenant_user_profiles as tp', function ($join) use ($tenantId) {
|
||||
$join->on('tp.user_id', '=', 'users.id')
|
||||
->where('tp.tenant_id', $tenantId);
|
||||
})
|
||||
->leftJoin('departments', 'departments.id', '=', 'tp.department_id')
|
||||
->leftJoin('positions as pos_rank', function ($join) use ($tenantId) {
|
||||
$join->on('pos_rank.tenant_id', '=', DB::raw($tenantId))
|
||||
->where('pos_rank.type', 'rank')
|
||||
->whereRaw('pos_rank.`key` COLLATE utf8mb4_unicode_ci = tp.position_key COLLATE utf8mb4_unicode_ci');
|
||||
})
|
||||
->leftJoin('positions as pos_title', function ($join) use ($tenantId) {
|
||||
$join->on('pos_title.tenant_id', '=', DB::raw($tenantId))
|
||||
->where('pos_title.type', 'title')
|
||||
->whereRaw('pos_title.`key` COLLATE utf8mb4_unicode_ci = tp.job_title_key COLLATE utf8mb4_unicode_ci');
|
||||
})
|
||||
->whereNull('users.deleted_at')
|
||||
->orderBy('departments.name')
|
||||
->orderBy('users.name')
|
||||
->select([
|
||||
'users.id',
|
||||
'users.name',
|
||||
'tp.department_id',
|
||||
'departments.name as department_name',
|
||||
DB::raw('COALESCE(pos_rank.name, tp.position_key, \'\') as position'),
|
||||
DB::raw('COALESCE(pos_title.name, tp.job_title_key, \'\') as job_title'),
|
||||
])
|
||||
->get();
|
||||
|
||||
$grouped = $users->groupBy(fn ($u) => $u->department_id ?? 'none');
|
||||
|
||||
$data = [];
|
||||
foreach ($grouped as $deptId => $deptUsers) {
|
||||
$first = $deptUsers->first();
|
||||
$data[] = [
|
||||
'department_id' => $deptId === 'none' ? null : (int) $deptId,
|
||||
'department_name' => $deptId === 'none' ? '미배정' : $first->department_name,
|
||||
'users' => $deptUsers->map(fn ($u) => [
|
||||
'id' => $u->id,
|
||||
'name' => $u->name,
|
||||
'position' => $u->position,
|
||||
'job_title' => $u->job_title,
|
||||
])->values()->toArray(),
|
||||
];
|
||||
}
|
||||
|
||||
// 미배정 그룹을 마지막으로
|
||||
usort($data, function ($a, $b) {
|
||||
if ($a['department_id'] === null) {
|
||||
return 1;
|
||||
}
|
||||
if ($b['department_id'] === null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return strcmp($a['department_name'], $b['department_name']);
|
||||
});
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user