Files
sam-manage/app/Http/Controllers/ESign/EsignVerificationController.php

215 lines
7.2 KiB
PHP

<?php
namespace App\Http\Controllers\ESign;
use App\Http\Controllers\Controller;
use App\Models\ESign\EsignHandwritingVerification;
use App\Models\ESign\EsignVerificationTemplate;
use App\Services\ESign\HandwritingVerificationService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
use Symfony\Component\HttpFoundation\Response;
class EsignVerificationController extends Controller
{
private HandwritingVerificationService $service;
public function __construct(HandwritingVerificationService $service)
{
$this->service = $service;
}
// ─── 화면 라우트 ───
public function dashboard(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('esign-verification.dashboard'));
}
return view('esign.verification.dashboard');
}
public function templates(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('esign-verification.templates'));
}
return view('esign.verification.templates');
}
public function demo(Request $request): View|Response
{
if ($request->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('esign-verification.demo'));
}
return view('esign.verification.demo');
}
// ─── API: 확인 템플릿 CRUD ───
public function indexTemplates(Request $request): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$templates = EsignVerificationTemplate::where('tenant_id', $tenantId)
->where('is_active', true)
->orderBy('created_at', 'desc')
->get();
return response()->json(['success' => true, 'data' => $templates]);
}
public function storeTemplate(Request $request): JsonResponse
{
$request->validate([
'name' => 'required|string|max:100',
'category' => 'nullable|string|max:50',
'steps' => 'required|array|min:1',
'steps.*.order' => 'required|integer|min:1',
'steps.*.text' => 'required|string|max:200',
'steps.*.threshold' => 'required|numeric|min:50|max:100',
'pass_threshold' => 'nullable|numeric|min:50|max:100',
'max_attempts' => 'nullable|integer|min:1|max:20',
]);
$tenantId = session('selected_tenant_id', 1);
$template = EsignVerificationTemplate::create([
'tenant_id' => $tenantId,
'name' => $request->input('name'),
'category' => $request->input('category'),
'steps' => $request->input('steps'),
'pass_threshold' => $request->input('pass_threshold', 80.00),
'max_attempts' => $request->input('max_attempts', 5),
'is_active' => true,
'created_by' => auth()->id(),
]);
return response()->json(['success' => true, 'data' => $template], 201);
}
public function showTemplate(int $id): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$template = EsignVerificationTemplate::where('tenant_id', $tenantId)
->findOrFail($id);
return response()->json(['success' => true, 'data' => $template]);
}
public function updateTemplate(Request $request, int $id): JsonResponse
{
$request->validate([
'name' => 'required|string|max:100',
'category' => 'nullable|string|max:50',
'steps' => 'required|array|min:1',
'steps.*.order' => 'required|integer|min:1',
'steps.*.text' => 'required|string|max:200',
'steps.*.threshold' => 'required|numeric|min:50|max:100',
'pass_threshold' => 'nullable|numeric|min:50|max:100',
'max_attempts' => 'nullable|integer|min:1|max:20',
]);
$tenantId = session('selected_tenant_id', 1);
$template = EsignVerificationTemplate::where('tenant_id', $tenantId)
->findOrFail($id);
$template->update([
'name' => $request->input('name'),
'category' => $request->input('category'),
'steps' => $request->input('steps'),
'pass_threshold' => $request->input('pass_threshold', 80.00),
'max_attempts' => $request->input('max_attempts', 5),
]);
return response()->json(['success' => true, 'data' => $template]);
}
public function destroyTemplate(int $id): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$template = EsignVerificationTemplate::where('tenant_id', $tenantId)
->findOrFail($id);
$template->update(['is_active' => false]);
return response()->json(['success' => true, 'message' => '템플릿이 비활성화되었습니다.']);
}
// ─── API: 데모 (인식 테스트) ───
public function demoRecognize(Request $request): JsonResponse
{
$request->validate([
'image' => 'required|string',
'expected_text' => 'required|string|max:200',
]);
$result = $this->service->demo(
$request->input('image'),
$request->input('expected_text'),
);
return response()->json(['success' => true, 'data' => $result]);
}
// ─── API: 검증 이력 ───
public function verificationHistory(Request $request): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$query = EsignHandwritingVerification::where('tenant_id', $tenantId)
->orderBy('created_at', 'desc');
if ($request->filled('contract_id')) {
$query->where('contract_id', $request->input('contract_id'));
}
$data = $query->limit(100)->get();
return response()->json(['success' => true, 'data' => $data]);
}
// ─── API: 통계 ───
public function stats(): JsonResponse
{
$tenantId = session('selected_tenant_id', 1);
$total = EsignHandwritingVerification::where('tenant_id', $tenantId)->count();
$passed = EsignHandwritingVerification::where('tenant_id', $tenantId)->where('is_passed', true)->count();
$failed = $total - $passed;
$avgScore = EsignHandwritingVerification::where('tenant_id', $tenantId)
->whereNotNull('similarity_score')
->avg('similarity_score') ?? 0;
$avgAttempts = EsignHandwritingVerification::where('tenant_id', $tenantId)
->where('is_passed', true)
->avg('attempt_number') ?? 0;
$templateCount = EsignVerificationTemplate::where('tenant_id', $tenantId)
->where('is_active', true)
->count();
return response()->json([
'success' => true,
'data' => [
'total_verifications' => $total,
'passed' => $passed,
'failed' => $failed,
'pass_rate' => $total > 0 ? round(($passed / $total) * 100, 1) : 0,
'avg_score' => round($avgScore, 1),
'avg_attempts' => round($avgAttempts, 1),
'template_count' => $templateCount,
],
]);
}
}