Phase 1 - 아카이브 복원 기능: - ArchiveService: 모델별 아카이브 로직 통합 (326줄) - RestoreService: 복원 로직 및 충돌 검사 (319줄) - ArchivedRecordController: restore, checkRestore 메서드 추가 - record_type enum→varchar 마이그레이션 - 복원 버튼 및 충돌 체크 UI (restore-check.blade.php) Phase 2 - 테넌트 필터링: - ArchivedRecord 모델: tenant_id fillable, tenant 관계 추가 - ArchiveService: tenant_id 저장 로직 (determineTenantId) - ArchivedRecordService: 테넌트별 필터링 쿼리 - 목록 UI: ID 컬럼, 대상 테넌트 컬럼 추가 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
119 lines
7.3 KiB
PHP
119 lines
7.3 KiB
PHP
<div class="overflow-x-auto">
|
|
<table class="min-w-full divide-y divide-gray-200">
|
|
<thead class="bg-gray-50">
|
|
<tr>
|
|
<th class="px-4 py-3 text-center text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 60px;">ID</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">작업 설명</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 150px;">대상 테넌트</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 180px;">대상 정보</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 100px;">레코드 타입</th>
|
|
<th class="px-4 py-3 text-center text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 70px;">레코드 수</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 100px;">삭제자</th>
|
|
<th class="px-4 py-3 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 140px;">삭제일시</th>
|
|
<th class="px-4 py-3 text-center text-xs font-semibold text-gray-700 uppercase tracking-wider" style="width: 60px;">작업</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="bg-white divide-y divide-gray-200">
|
|
@forelse($records as $record)
|
|
@php
|
|
$types = explode(',', $record->record_types ?? '');
|
|
$primaryType = $types[0] ?? '';
|
|
// 대상 정보 결정 (테넌트 > 사용자)
|
|
$targetName = $record->target_company_name ?? $record->target_name ?? '-';
|
|
$targetSub = '';
|
|
if ($primaryType === 'tenant' && $record->target_code) {
|
|
$targetSub = "코드: {$record->target_code}";
|
|
} elseif ($primaryType === 'user' && $record->target_email) {
|
|
$targetSub = $record->target_email;
|
|
}
|
|
// 대상 테넌트 조회
|
|
$targetTenant = $record->tenant_id ? \App\Models\Tenants\Tenant::find($record->tenant_id) : null;
|
|
$targetTenantName = $targetTenant?->company_name ?? ($record->tenant_id ? "(삭제됨 ID: {$record->tenant_id})" : '-');
|
|
@endphp
|
|
<tr class="hover:bg-gray-50">
|
|
<td class="px-4 py-4 text-center text-sm text-gray-500 font-mono">
|
|
{{ $record->id }}
|
|
</td>
|
|
<td class="px-4 py-4 text-sm text-gray-900">
|
|
<div class="font-medium">{{ $record->batch_description ?? '삭제 작업' }}</div>
|
|
</td>
|
|
<td class="px-4 py-4 text-sm text-gray-900">
|
|
@if($targetTenant)
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-indigo-100 text-indigo-800">
|
|
{{ $targetTenantName }}
|
|
</span>
|
|
@elseif($record->tenant_id)
|
|
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-600">
|
|
삭제됨 (ID: {{ $record->tenant_id }})
|
|
</span>
|
|
@else
|
|
<span class="text-gray-400">-</span>
|
|
@endif
|
|
</td>
|
|
<td class="px-6 py-4 text-sm">
|
|
<div class="font-medium text-gray-900">{{ $targetName }}</div>
|
|
@if($targetSub)
|
|
<div class="text-xs text-gray-500 mt-0.5">{{ $targetSub }}</div>
|
|
@endif
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap">
|
|
<div class="flex flex-wrap gap-1">
|
|
@foreach($types as $type)
|
|
@if($type === 'tenant')
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">테넌트</span>
|
|
@elseif($type === 'user')
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">사용자</span>
|
|
@else
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-800">{{ $type }}</span>
|
|
@endif
|
|
@endforeach
|
|
</div>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-center">
|
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800">
|
|
{{ $record->record_count }}건
|
|
</span>
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
|
@php
|
|
$deletedByUser = $record->deleted_by ? \App\Models\User::find($record->deleted_by) : null;
|
|
@endphp
|
|
{{ $deletedByUser?->name ?? '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
|
{{ $record->deleted_at ? \Carbon\Carbon::parse($record->deleted_at)->format('Y-m-d H:i') : '-' }}
|
|
</td>
|
|
<td class="px-6 py-4 whitespace-nowrap text-center">
|
|
<a href="{{ route('archived-records.show', $record->batch_id) }}"
|
|
class="text-blue-600 hover:text-blue-900 transition"
|
|
title="상세 보기">
|
|
<svg class="w-5 h-5 inline" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
|
</svg>
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="9" class="px-6 py-12 text-center text-gray-500">
|
|
<div class="flex flex-col items-center">
|
|
<svg class="w-12 h-12 text-gray-300 mb-3" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 8h14M5 8a2 2 0 110-4h14a2 2 0 110 4M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8m-9 4h4" />
|
|
</svg>
|
|
<p>백업된 데이터가 없습니다.</p>
|
|
</div>
|
|
</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{{-- 페이지네이션 (공용 컴포넌트) --}}
|
|
@include('partials.pagination', [
|
|
'paginator' => $records,
|
|
'target' => '#archived-record-table',
|
|
'includeForm' => '#filterForm'
|
|
])
|