Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
2026-01-30 13:51:49 +09:00
97 changed files with 13237 additions and 4176 deletions

View File

@@ -18,6 +18,7 @@
use App\Http\Controllers\FcmController;
use App\Http\Controllers\ItemFieldController;
use App\Http\Controllers\Lab\AIController;
use App\Http\Controllers\Lab\ManagementController;
use App\Http\Controllers\Lab\StrategyController;
use App\Http\Controllers\MenuController;
use App\Http\Controllers\MenuSyncController;
@@ -30,6 +31,7 @@
use App\Http\Controllers\QuoteFormulaController;
use App\Http\Controllers\RoleController;
use App\Http\Controllers\RolePermissionController;
use App\Http\Controllers\Sales\SalesProductController;
use App\Http\Controllers\System\AiConfigController;
use App\Http\Controllers\TenantController;
use App\Http\Controllers\TenantSettingController;
@@ -356,6 +358,7 @@
Route::delete('/{id}', [AiConfigController::class, 'destroy'])->name('destroy');
Route::post('/{id}/toggle', [AiConfigController::class, 'toggle'])->name('toggle');
Route::post('/test', [AiConfigController::class, 'test'])->name('test');
Route::post('/test-gcs', [AiConfigController::class, 'testGcs'])->name('test-gcs');
});
// 명함 OCR API
@@ -458,6 +461,9 @@
Route::get('/inquiry/{inquiryKey}/report', [\App\Http\Controllers\Credit\CreditController::class, 'getReportData'])->name('inquiry.report');
Route::delete('/inquiry/{id}', [\App\Http\Controllers\Credit\CreditController::class, 'deleteInquiry'])->name('inquiry.destroy');
// 조회회수 집계
Route::get('/usage', [\App\Http\Controllers\Credit\CreditUsageController::class, 'index'])->name('usage.index');
// 설정 관리
Route::get('/settings', [\App\Http\Controllers\Credit\CreditController::class, 'settings'])->name('settings.index');
Route::get('/settings/create', [\App\Http\Controllers\Credit\CreditController::class, 'createConfig'])->name('settings.create');
@@ -486,10 +492,7 @@
Route::prefix('lab')->name('lab.')->group(function () {
// S. 전략 (Strategy)
Route::prefix('strategy')->name('strategy.')->group(function () {
Route::get('/tax', [StrategyController::class, 'tax'])->name('tax');
Route::get('/labor', [StrategyController::class, 'labor'])->name('labor');
Route::get('/debt', [StrategyController::class, 'debt'])->name('debt');
Route::get('/mrp-overseas', [StrategyController::class, 'mrpOverseas'])->name('mrp-overseas');
Route::get('/chatbot', [StrategyController::class, 'chatbot'])->name('chatbot');
Route::get('/knowledge-search', [StrategyController::class, 'knowledgeSearch'])->name('knowledge-search');
Route::get('/chatbot-compare', [StrategyController::class, 'chatbotCompare'])->name('chatbot-compare');
@@ -498,17 +501,6 @@
Route::get('/confluence-vs-notion', [StrategyController::class, 'confluenceVsNotion'])->name('confluence-vs-notion');
Route::get('/sales-strategy', [StrategyController::class, 'salesStrategy'])->name('sales-strategy');
});
// A. AI/자동화 (AI/Automation)
Route::prefix('ai')->name('ai.')->group(function () {
Route::get('/web-recording', [AIController::class, 'webRecording'])->name('web-recording');
Route::get('/meeting-summary', [AIController::class, 'meetingSummary'])->name('meeting-summary');
Route::get('/work-memo-summary', [AIController::class, 'workMemoSummary'])->name('work-memo-summary');
Route::get('/operator-chatbot', [AIController::class, 'operatorChatbot'])->name('operator-chatbot');
Route::get('/vertex-rag', [AIController::class, 'vertexRag'])->name('vertex-rag');
Route::get('/tenant-knowledge', [AIController::class, 'tenantKnowledge'])->name('tenant-knowledge');
Route::get('/tenant-chatbot', [AIController::class, 'tenantChatbot'])->name('tenant-chatbot');
});
});
/*
@@ -738,14 +730,25 @@
return view('finance.purchase');
})->name('purchase');
// 정산관리
Route::get('/sales-commission', function () {
if (request()->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('finance.sales-commission'));
}
// 영업수수료정산 (실제 구현)
Route::prefix('sales-commissions')->name('sales-commissions.')->group(function () {
Route::get('/', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'index'])->name('index');
Route::get('/export', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'export'])->name('export');
Route::get('/payment-form', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'paymentForm'])->name('payment-form');
Route::get('/table', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'table'])->name('table');
Route::get('/stats', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'stats'])->name('stats');
Route::post('/payment', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'registerPayment'])->name('payment');
Route::post('/bulk-approve', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'bulkApprove'])->name('bulk-approve');
Route::post('/bulk-mark-paid', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'bulkMarkPaid'])->name('bulk-mark-paid');
Route::get('/{id}', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'show'])->name('show');
Route::get('/{id}/detail', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'detail'])->name('detail');
Route::post('/{id}/approve', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'approve'])->name('approve');
Route::post('/{id}/mark-paid', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'markPaid'])->name('mark-paid');
Route::post('/{id}/cancel', [\App\Http\Controllers\Finance\SalesCommissionController::class, 'cancel'])->name('cancel');
});
return view('finance.sales-commission');
})->name('sales-commission');
// 기존 sales-commission URL 리다이렉트 (호환성)
Route::get('/sales-commission', fn() => redirect()->route('finance.sales-commissions.index'))->name('sales-commission');
Route::get('/consulting-fee', function () {
if (request()->header('HX-Request')) {
return response('', 200)->header('HX-Redirect', route('finance.consulting-fee'));
@@ -842,9 +845,12 @@
// 영업관리 대시보드
Route::get('salesmanagement/dashboard', [\App\Http\Controllers\Sales\SalesDashboardController::class, 'index'])->name('salesmanagement.dashboard');
Route::get('salesmanagement/dashboard/refresh', [\App\Http\Controllers\Sales\SalesDashboardController::class, 'refresh'])->name('salesmanagement.dashboard.refresh');
Route::get('salesmanagement/dashboard/tenants', [\App\Http\Controllers\Sales\SalesDashboardController::class, 'refreshTenantList'])->name('salesmanagement.dashboard.tenants');
// 영업 담당자 관리
Route::resource('managers', \App\Http\Controllers\Sales\SalesManagerController::class);
Route::get('managers/{id}/modal-show', [\App\Http\Controllers\Sales\SalesManagerController::class, 'modalShow'])->name('managers.modal-show');
Route::get('managers/{id}/modal-edit', [\App\Http\Controllers\Sales\SalesManagerController::class, 'modalEdit'])->name('managers.modal-edit');
Route::post('managers/{id}/approve', [\App\Http\Controllers\Sales\SalesManagerController::class, 'approve'])->name('managers.approve');
Route::post('managers/{id}/reject', [\App\Http\Controllers\Sales\SalesManagerController::class, 'reject'])->name('managers.reject');
Route::post('managers/{id}/delegate-role', [\App\Http\Controllers\Sales\SalesManagerController::class, 'delegateRole'])->name('managers.delegate-role');
@@ -858,7 +864,60 @@
Route::post('prospects/{id}/convert', [\App\Http\Controllers\Sales\TenantProspectController::class, 'convert'])->name('prospects.convert');
Route::post('prospects/check-business-number', [\App\Http\Controllers\Sales\TenantProspectController::class, 'checkBusinessNumber'])->name('prospects.check-business-number');
Route::delete('prospects/{id}/attachment', [\App\Http\Controllers\Sales\TenantProspectController::class, 'deleteAttachment'])->name('prospects.delete-attachment');
Route::get('prospects/{id}/modal-show', [\App\Http\Controllers\Sales\TenantProspectController::class, 'modalShow'])->name('prospects.modal-show');
Route::get('prospects/{id}/modal-edit', [\App\Http\Controllers\Sales\TenantProspectController::class, 'modalEdit'])->name('prospects.modal-edit');
// 영업 실적 관리
Route::resource('records', \App\Http\Controllers\Sales\SalesRecordController::class);
// 영업 시나리오 관리
Route::prefix('scenarios')->name('scenarios.')->group(function () {
Route::get('/{tenant}/sales', [\App\Http\Controllers\Sales\SalesScenarioController::class, 'salesScenario'])->name('sales');
Route::get('/{tenant}/manager', [\App\Http\Controllers\Sales\SalesScenarioController::class, 'managerScenario'])->name('manager');
Route::post('/checklist/toggle', [\App\Http\Controllers\Sales\SalesScenarioController::class, 'toggleChecklist'])->name('checklist.toggle');
Route::get('/{tenant}/{type}/progress', [\App\Http\Controllers\Sales\SalesScenarioController::class, 'getProgress'])->name('progress');
});
// 상담 기록 관리
Route::prefix('consultations')->name('consultations.')->group(function () {
Route::get('/{tenant}', [\App\Http\Controllers\Sales\ConsultationController::class, 'index'])->name('index');
Route::post('/', [\App\Http\Controllers\Sales\ConsultationController::class, 'store'])->name('store');
Route::delete('/{consultation}', [\App\Http\Controllers\Sales\ConsultationController::class, 'destroy'])->name('destroy');
Route::post('/upload-audio', [\App\Http\Controllers\Sales\ConsultationController::class, 'uploadAudio'])->name('upload-audio');
Route::post('/upload-file', [\App\Http\Controllers\Sales\ConsultationController::class, 'uploadFile'])->name('upload-file');
Route::delete('/file/{file}', [\App\Http\Controllers\Sales\ConsultationController::class, 'deleteFile'])->name('delete-file');
Route::get('/download-audio/{consultation}', [\App\Http\Controllers\Sales\ConsultationController::class, 'downloadAudio'])->name('download-audio');
Route::get('/download-file/{consultation}', [\App\Http\Controllers\Sales\ConsultationController::class, 'downloadFile'])->name('download-file');
});
// 매니저 지정 변경
Route::post('/tenants/{tenant}/assign-manager', [\App\Http\Controllers\Sales\SalesDashboardController::class, 'assignManager'])->name('tenants.assign-manager');
// 매니저 목록 조회 (드롭다운용)
Route::get('/managers/list', [\App\Http\Controllers\Sales\SalesDashboardController::class, 'getManagers'])->name('managers.list');
// 상품관리 (HQ 전용)
Route::prefix('products')->name('products.')->group(function () {
Route::get('/', [SalesProductController::class, 'index'])->name('index');
Route::get('/list', [SalesProductController::class, 'productList'])->name('list');
Route::post('/', [SalesProductController::class, 'store'])->name('store');
Route::put('/{id}', [SalesProductController::class, 'update'])->name('update');
Route::delete('/{id}', [SalesProductController::class, 'destroy'])->name('destroy');
Route::post('/{id}/toggle', [SalesProductController::class, 'toggleActive'])->name('toggle');
Route::post('/reorder', [SalesProductController::class, 'reorder'])->name('reorder');
// 카테고리 관리
Route::prefix('categories')->name('categories.')->group(function () {
Route::get('/', [SalesProductController::class, 'categories'])->name('index');
Route::post('/', [SalesProductController::class, 'storeCategory'])->name('store');
Route::put('/{id}', [SalesProductController::class, 'updateCategory'])->name('update');
Route::delete('/{id}', [SalesProductController::class, 'deleteCategory'])->name('destroy');
});
// API (영업 시나리오용)
Route::get('/api/list', [SalesProductController::class, 'getProductsApi'])->name('api.list');
});
// 계약관리
Route::prefix('contracts')->name('contracts.')->group(function () {
Route::post('/products', [\App\Http\Controllers\Sales\SalesContractController::class, 'saveProducts'])->name('products.save');
Route::get('/products/{tenant}', [\App\Http\Controllers\Sales\SalesContractController::class, 'getProducts'])->name('products.get');
});
});