refactor:영업관리 데이터를 DB 테이블로 변경
- 모델 추가: SalesPartner, SalesTenantManagement, SalesScenarioChecklist, SalesConsultation - 모델 위치 이동: app/Models/ → app/Models/Sales/ - 컨트롤러 수정: 캐시 대신 DB 모델 사용 - 뷰 수정: Eloquent 모델 속성 사용 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
namespace App\Http\Controllers\Sales;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Sales\SalesConsultation;
|
||||
use App\Models\Tenants\Tenant;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\View\View;
|
||||
@@ -14,6 +14,7 @@
|
||||
* 상담 기록 관리 컨트롤러
|
||||
*
|
||||
* 테넌트별 상담 기록(텍스트, 음성, 파일)을 관리합니다.
|
||||
* 데이터는 sales_consultations 테이블에 저장됩니다.
|
||||
*/
|
||||
class ConsultationController extends Controller
|
||||
{
|
||||
@@ -26,17 +27,8 @@ public function index(int $tenantId, Request $request): View
|
||||
$scenarioType = $request->input('scenario_type', 'sales');
|
||||
$stepId = $request->input('step_id');
|
||||
|
||||
// 캐시에서 상담 기록 조회
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
|
||||
// 특정 단계 필터링
|
||||
if ($stepId) {
|
||||
$consultations = array_filter($consultations, fn($c) => ($c['step_id'] ?? null) == $stepId);
|
||||
}
|
||||
|
||||
// 최신순 정렬
|
||||
usort($consultations, fn($a, $b) => strtotime($b['created_at']) - strtotime($a['created_at']));
|
||||
// DB에서 상담 기록 조회
|
||||
$consultations = SalesConsultation::getByTenantAndType($tenantId, $scenarioType, $stepId);
|
||||
|
||||
return view('sales.modals.consultation-log', [
|
||||
'tenant' => $tenant,
|
||||
@@ -58,77 +50,36 @@ public function store(Request $request): JsonResponse
|
||||
'content' => 'required|string|max:5000',
|
||||
]);
|
||||
|
||||
$tenantId = $request->input('tenant_id');
|
||||
$scenarioType = $request->input('scenario_type');
|
||||
$stepId = $request->input('step_id');
|
||||
$content = $request->input('content');
|
||||
$consultation = SalesConsultation::createText(
|
||||
$request->input('tenant_id'),
|
||||
$request->input('scenario_type'),
|
||||
$request->input('step_id'),
|
||||
$request->input('content')
|
||||
);
|
||||
|
||||
// 캐시 키
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
|
||||
// 새 상담 기록 추가
|
||||
$consultation = [
|
||||
'id' => uniqid('cons_'),
|
||||
'type' => 'text',
|
||||
'content' => $content,
|
||||
'step_id' => $stepId,
|
||||
'created_by' => auth()->id(),
|
||||
'created_by_name' => auth()->user()->name,
|
||||
'created_at' => now()->toDateTimeString(),
|
||||
];
|
||||
|
||||
$consultations[] = $consultation;
|
||||
|
||||
// 캐시에 저장 (90일 유지)
|
||||
cache()->put($cacheKey, $consultations, now()->addDays(90));
|
||||
$consultation->load('creator');
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'consultation' => $consultation,
|
||||
'consultation' => [
|
||||
'id' => $consultation->id,
|
||||
'type' => $consultation->consultation_type,
|
||||
'content' => $consultation->content,
|
||||
'created_by_name' => $consultation->creator->name,
|
||||
'created_at' => $consultation->created_at->format('Y-m-d H:i'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 상담 기록 삭제
|
||||
*/
|
||||
public function destroy(string $consultationId, Request $request): JsonResponse
|
||||
public function destroy(int $consultationId, Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'tenant_id' => 'required|integer|exists:tenants,id',
|
||||
'scenario_type' => 'required|in:sales,manager',
|
||||
]);
|
||||
$consultation = SalesConsultation::findOrFail($consultationId);
|
||||
|
||||
$tenantId = $request->input('tenant_id');
|
||||
$scenarioType = $request->input('scenario_type');
|
||||
|
||||
// 캐시 키
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
|
||||
// 상담 기록 찾기 및 삭제
|
||||
$found = false;
|
||||
foreach ($consultations as $index => $consultation) {
|
||||
if ($consultation['id'] === $consultationId) {
|
||||
// 파일이 있으면 삭제
|
||||
if (isset($consultation['file_path'])) {
|
||||
Storage::delete($consultation['file_path']);
|
||||
}
|
||||
unset($consultations[$index]);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$found) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '상담 기록을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
// 캐시에 저장
|
||||
cache()->put($cacheKey, array_values($consultations), now()->addDays(90));
|
||||
// 파일이 있으면 함께 삭제
|
||||
$consultation->deleteWithFile();
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
@@ -160,32 +111,32 @@ public function uploadAudio(Request $request): JsonResponse
|
||||
$fileName = 'audio_' . now()->format('Ymd_His') . '_' . uniqid() . '.' . $file->getClientOriginalExtension();
|
||||
$path = $file->storeAs("tenant/consultations/{$tenantId}", $fileName, 'local');
|
||||
|
||||
// 캐시 키
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
// DB에 저장
|
||||
$consultation = SalesConsultation::createAudio(
|
||||
$tenantId,
|
||||
$scenarioType,
|
||||
$stepId,
|
||||
$path,
|
||||
$fileName,
|
||||
$file->getSize(),
|
||||
$transcript,
|
||||
$duration
|
||||
);
|
||||
|
||||
// 새 상담 기록 추가
|
||||
$consultation = [
|
||||
'id' => uniqid('cons_'),
|
||||
'type' => 'audio',
|
||||
'file_path' => $path,
|
||||
'file_name' => $fileName,
|
||||
'transcript' => $transcript,
|
||||
'duration' => $duration,
|
||||
'step_id' => $stepId,
|
||||
'created_by' => auth()->id(),
|
||||
'created_by_name' => auth()->user()->name,
|
||||
'created_at' => now()->toDateTimeString(),
|
||||
];
|
||||
|
||||
$consultations[] = $consultation;
|
||||
|
||||
// 캐시에 저장
|
||||
cache()->put($cacheKey, $consultations, now()->addDays(90));
|
||||
$consultation->load('creator');
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'consultation' => $consultation,
|
||||
'consultation' => [
|
||||
'id' => $consultation->id,
|
||||
'type' => $consultation->consultation_type,
|
||||
'file_name' => $consultation->file_name,
|
||||
'transcript' => $consultation->transcript,
|
||||
'duration' => $consultation->duration,
|
||||
'formatted_duration' => $consultation->formatted_duration,
|
||||
'created_by_name' => $consultation->creator->name,
|
||||
'created_at' => $consultation->created_at->format('Y-m-d H:i'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -211,76 +162,38 @@ public function uploadFile(Request $request): JsonResponse
|
||||
$fileName = now()->format('Ymd_His') . '_' . uniqid() . '_' . $originalName;
|
||||
$path = $file->storeAs("tenant/attachments/{$tenantId}", $fileName, 'local');
|
||||
|
||||
// 캐시 키
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
// DB에 저장
|
||||
$consultation = SalesConsultation::createFile(
|
||||
$tenantId,
|
||||
$scenarioType,
|
||||
$stepId,
|
||||
$path,
|
||||
$originalName,
|
||||
$file->getSize(),
|
||||
$file->getMimeType()
|
||||
);
|
||||
|
||||
// 새 상담 기록 추가
|
||||
$consultation = [
|
||||
'id' => uniqid('cons_'),
|
||||
'type' => 'file',
|
||||
'file_path' => $path,
|
||||
'file_name' => $originalName,
|
||||
'file_size' => $file->getSize(),
|
||||
'file_type' => $file->getMimeType(),
|
||||
'step_id' => $stepId,
|
||||
'created_by' => auth()->id(),
|
||||
'created_by_name' => auth()->user()->name,
|
||||
'created_at' => now()->toDateTimeString(),
|
||||
];
|
||||
|
||||
$consultations[] = $consultation;
|
||||
|
||||
// 캐시에 저장
|
||||
cache()->put($cacheKey, $consultations, now()->addDays(90));
|
||||
$consultation->load('creator');
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'consultation' => $consultation,
|
||||
'consultation' => [
|
||||
'id' => $consultation->id,
|
||||
'type' => $consultation->consultation_type,
|
||||
'file_name' => $consultation->file_name,
|
||||
'file_size' => $consultation->file_size,
|
||||
'formatted_file_size' => $consultation->formatted_file_size,
|
||||
'created_by_name' => $consultation->creator->name,
|
||||
'created_at' => $consultation->created_at->format('Y-m-d H:i'),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 삭제
|
||||
*/
|
||||
public function deleteFile(string $fileId, Request $request): JsonResponse
|
||||
public function deleteFile(int $fileId, Request $request): JsonResponse
|
||||
{
|
||||
return $this->destroy($fileId, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 다운로드 URL 생성
|
||||
*/
|
||||
public function getDownloadUrl(string $consultationId, Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'tenant_id' => 'required|integer|exists:tenants,id',
|
||||
'scenario_type' => 'required|in:sales,manager',
|
||||
]);
|
||||
|
||||
$tenantId = $request->input('tenant_id');
|
||||
$scenarioType = $request->input('scenario_type');
|
||||
|
||||
// 캐시 키
|
||||
$cacheKey = "consultations:{$tenantId}:{$scenarioType}";
|
||||
$consultations = cache()->get($cacheKey, []);
|
||||
|
||||
// 상담 기록 찾기
|
||||
$consultation = collect($consultations)->firstWhere('id', $consultationId);
|
||||
|
||||
if (!$consultation || !isset($consultation['file_path'])) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => '파일을 찾을 수 없습니다.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
// 임시 다운로드 URL 생성 (5분 유효)
|
||||
$url = Storage::temporaryUrl($consultation['file_path'], now()->addMinutes(5));
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'url' => $url,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user