chore: [misc] 거래처 통계 수정 + 문서 템플릿 file_id 추가 + 라우트 정리
- ClientService stats() active/inactive 카운트 추가 - DocumentTemplateSection file_id 컬럼 마이그레이션 - 논리 관계 문서 업데이트 (BendingItemMapping 추가)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# 논리적 데이터베이스 관계 문서
|
||||
|
||||
> **자동 생성**: 2026-03-12 13:58:25
|
||||
> **자동 생성**: 2026-03-17 13:34:26
|
||||
> **소스**: Eloquent 모델 관계 분석
|
||||
|
||||
## 📊 모델별 관계 현황
|
||||
@@ -374,6 +374,8 @@ ### esign_signers
|
||||
### equipments
|
||||
**모델**: `App\Models\Equipment\Equipment`
|
||||
|
||||
- **manager()**: belongsTo → `users`
|
||||
- **subManager()**: belongsTo → `users`
|
||||
- **inspectionTemplates()**: hasMany → `equipment_inspection_templates`
|
||||
- **inspections()**: hasMany → `equipment_inspections`
|
||||
- **repairs()**: hasMany → `equipment_repairs`
|
||||
@@ -384,6 +386,7 @@ ### equipment_inspections
|
||||
**모델**: `App\Models\Equipment\EquipmentInspection`
|
||||
|
||||
- **equipment()**: belongsTo → `equipments`
|
||||
- **inspector()**: belongsTo → `users`
|
||||
- **details()**: hasMany → `equipment_inspection_details`
|
||||
|
||||
### equipment_inspection_details
|
||||
@@ -407,6 +410,7 @@ ### equipment_repairs
|
||||
**모델**: `App\Models\Equipment\EquipmentRepair`
|
||||
|
||||
- **equipment()**: belongsTo → `equipments`
|
||||
- **repairer()**: belongsTo → `users`
|
||||
|
||||
### estimates
|
||||
**모델**: `App\Models\Estimate\Estimate`
|
||||
@@ -429,6 +433,12 @@ ### file_share_links
|
||||
- **file()**: belongsTo → `files`
|
||||
- **tenant()**: belongsTo → `tenants`
|
||||
|
||||
### corporate_vehicles
|
||||
**모델**: `App\Models\Tenants\CorporateVehicle`
|
||||
|
||||
- **logs()**: hasMany → `vehicle_logs`
|
||||
- **maintenances()**: hasMany → `vehicle_maintenances`
|
||||
|
||||
### folders
|
||||
**모델**: `App\Models\Folder`
|
||||
|
||||
@@ -713,6 +723,11 @@ ### process_steps
|
||||
|
||||
- **process()**: belongsTo → `processes`
|
||||
|
||||
### bending_item_mappings
|
||||
**모델**: `App\Models\Production\BendingItemMapping`
|
||||
|
||||
- **item()**: belongsTo → `items`
|
||||
|
||||
### work_orders
|
||||
**모델**: `App\Models\Production\WorkOrder`
|
||||
|
||||
@@ -898,6 +913,7 @@ ### quality_documents
|
||||
- **documentOrders()**: hasMany → `quality_document_orders`
|
||||
- **locations()**: hasMany → `quality_document_locations`
|
||||
- **performanceReport()**: hasOne → `performance_reports`
|
||||
- **file()**: hasOne → `files`
|
||||
|
||||
### quality_document_locations
|
||||
**모델**: `App\Models\Qualitys\QualityDocumentLocation`
|
||||
@@ -1232,6 +1248,7 @@ ### shipments
|
||||
|
||||
- **order()**: belongsTo → `orders`
|
||||
- **workOrder()**: belongsTo → `work_orders`
|
||||
- **client()**: belongsTo → `clients`
|
||||
- **creator()**: belongsTo → `users`
|
||||
- **updater()**: belongsTo → `users`
|
||||
- **items()**: hasMany → `shipment_items`
|
||||
@@ -1242,6 +1259,7 @@ ### shipment_items
|
||||
|
||||
- **shipment()**: belongsTo → `shipments`
|
||||
- **stockLot()**: belongsTo → `stock_lots`
|
||||
- **orderItem()**: belongsTo → `order_items`
|
||||
|
||||
### shipment_vehicle_dispatchs
|
||||
**모델**: `App\Models\Tenants\ShipmentVehicleDispatch`
|
||||
@@ -1353,6 +1371,16 @@ ### today_issues
|
||||
- **reader()**: belongsTo → `users`
|
||||
- **targetUser()**: belongsTo → `users`
|
||||
|
||||
### vehicle_logs
|
||||
**모델**: `App\Models\Tenants\VehicleLog`
|
||||
|
||||
- **vehicle()**: belongsTo → `corporate_vehicles`
|
||||
|
||||
### vehicle_maintenances
|
||||
**모델**: `App\Models\Tenants\VehicleMaintenance`
|
||||
|
||||
- **vehicle()**: belongsTo → `corporate_vehicles`
|
||||
|
||||
### withdrawals
|
||||
**모델**: `App\Models\Tenants\Withdrawal`
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* @property int $id
|
||||
* @property int $template_id
|
||||
* @property string $title 섹션 제목
|
||||
* @property string|null $image_path 검사 기준 이미지 경로
|
||||
* @property string|null $image_path 검사 기준 이미지 경로 (R2 key)
|
||||
* @property int|null $file_id 도해 이미지 파일 ID (files 테이블 참조)
|
||||
* @property int $sort_order 정렬 순서
|
||||
*/
|
||||
class DocumentTemplateSection extends Model
|
||||
@@ -24,6 +25,7 @@ class DocumentTemplateSection extends Model
|
||||
'title',
|
||||
'description',
|
||||
'image_path',
|
||||
'file_id',
|
||||
'sort_order',
|
||||
];
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ public function index(array $params)
|
||||
$query->whereDate('created_at', '<=', $endDate);
|
||||
}
|
||||
|
||||
$query->orderBy('client_code')->orderBy('id');
|
||||
$query->orderBy('id', 'desc');
|
||||
|
||||
$paginator = $query->paginate($size, ['*'], 'page', $page);
|
||||
|
||||
@@ -304,10 +304,14 @@ public function stats(): array
|
||||
{
|
||||
$tenantId = $this->tenantId();
|
||||
|
||||
$total = Client::where('tenant_id', $tenantId)->count();
|
||||
$base = Client::where('tenant_id', $tenantId);
|
||||
|
||||
$total = (clone $base)->count();
|
||||
$active = (clone $base)->where('is_active', true)->count();
|
||||
$inactive = $total - $active;
|
||||
|
||||
// 거래처 유형별 통계
|
||||
$typeCounts = Client::where('tenant_id', $tenantId)
|
||||
$typeCounts = (clone $base)
|
||||
->selectRaw('client_type, COUNT(*) as count')
|
||||
->groupBy('client_type')
|
||||
->pluck('count', 'client_type')
|
||||
@@ -321,12 +325,14 @@ public function stats(): array
|
||||
->distinct('client_id')
|
||||
->pluck('client_id');
|
||||
|
||||
$badDebtCount = Client::where('tenant_id', $tenantId)
|
||||
$badDebtCount = (clone $base)
|
||||
->whereIn('id', $badDebtClientIds)
|
||||
->count();
|
||||
|
||||
return [
|
||||
'total' => $total,
|
||||
'active' => $active,
|
||||
'inactive' => $inactive,
|
||||
'sales' => $typeCounts['SALES'] ?? 0,
|
||||
'purchase' => $typeCounts['PURCHASE'] ?? 0,
|
||||
'both' => $typeCounts['BOTH'] ?? 0,
|
||||
|
||||
@@ -982,6 +982,7 @@ public function formatTemplateForReact(DocumentTemplate $template): array
|
||||
'name' => $section->title,
|
||||
'title' => $section->title,
|
||||
'image_path' => $section->image_path,
|
||||
'file_id' => $section->file_id,
|
||||
'sort_order' => $section->sort_order,
|
||||
'items' => $section->items->map(function ($item) use ($methodCodes) {
|
||||
// method 코드를 한글 이름으로 변환
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('document_template_sections', function (Blueprint $table) {
|
||||
$table->unsignedBigInteger('file_id')->nullable()->after('image_path')
|
||||
->comment('도해 이미지 파일 ID (files 테이블 참조)');
|
||||
});
|
||||
|
||||
// 기존 image_path → file_id 백필 (files.file_path와 매칭)
|
||||
DB::statement('
|
||||
UPDATE document_template_sections dts
|
||||
INNER JOIN files f ON f.file_path = dts.image_path AND f.deleted_at IS NULL
|
||||
SET dts.file_id = f.id
|
||||
WHERE dts.image_path IS NOT NULL AND dts.file_id IS NULL
|
||||
');
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('document_template_sections', function (Blueprint $table) {
|
||||
$table->dropColumn('file_id');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -38,14 +38,19 @@
|
||||
]);
|
||||
})->where('path', '.*');
|
||||
|
||||
// R2 테넌트 파일 프록시 (문서 템플릿 이미지 등, 인증 불필요, 캐시 1일)
|
||||
Route::get('/storage/tenants/{path}', function (string $path) {
|
||||
if (! Storage::disk('r2')->exists($path)) {
|
||||
// R2 파일 프록시 (file_id 기반, 인증 불필요, 캐시 1일)
|
||||
Route::get('/files/{id}/view', function (int $id) {
|
||||
$file = \App\Models\File::find($id);
|
||||
if (! $file || ! $file->file_path) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$mime = Storage::disk('r2')->mimeType($path);
|
||||
$stream = Storage::disk('r2')->readStream($path);
|
||||
if (! Storage::disk('r2')->exists($file->file_path)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$mime = Storage::disk('r2')->mimeType($file->file_path);
|
||||
$stream = Storage::disk('r2')->readStream($file->file_path);
|
||||
|
||||
return response()->stream(function () use ($stream) {
|
||||
fpassthru($stream);
|
||||
@@ -56,7 +61,7 @@
|
||||
'Content-Type' => $mime,
|
||||
'Cache-Control' => 'public, max-age=86400',
|
||||
]);
|
||||
})->where('path', '.*');
|
||||
});
|
||||
|
||||
// Swagger 설정
|
||||
Route::get('/docs/api-docs.json', function () {
|
||||
|
||||
Reference in New Issue
Block a user