diff --git a/app/Http/Controllers/Sales/SalesProspectController.php b/app/Http/Controllers/Sales/SalesProspectController.php index d602103c..396f36e2 100644 --- a/app/Http/Controllers/Sales/SalesProspectController.php +++ b/app/Http/Controllers/Sales/SalesProspectController.php @@ -8,6 +8,7 @@ use App\Models\Sales\SalesProspectProduct; use Illuminate\Http\Request; use Illuminate\Http\Response; +use Illuminate\Support\Facades\Storage; use Illuminate\View\View; /** @@ -92,8 +93,15 @@ public function store(Request $request) 'email' => 'nullable|email|max:100', 'address' => 'nullable|string|max:500', 'status' => 'required|in:lead,prospect,negotiation,contracted,lost', + 'business_card_image_data' => 'nullable|string', ]); + // 명함 이미지 저장 (Base64) + if (!empty($validated['business_card_image_data'])) { + $validated['business_card_image'] = $this->saveBusinessCardImage($validated['business_card_image_data']); + unset($validated['business_card_image_data']); + } + $prospect = SalesProspect::create($validated); return redirect()->route('sales.prospects.show', $prospect->id) @@ -148,8 +156,21 @@ public function update(Request $request, int $id) 'email' => 'nullable|email|max:100', 'address' => 'nullable|string|max:500', 'status' => 'required|in:lead,prospect,negotiation,contracted,lost', + 'business_card' => 'nullable|image|max:5120', ]); + // 명함 이미지 업로드 처리 + if ($request->hasFile('business_card')) { + // 기존 이미지 삭제 + if ($prospect->business_card_image) { + Storage::disk('public')->delete($prospect->business_card_image); + } + + $validated['business_card_image'] = $request->file('business_card') + ->store('business-cards', 'public'); + } + unset($validated['business_card']); + $prospect->update($validated); return redirect()->route('sales.prospects.show', $prospect->id) @@ -162,9 +183,39 @@ public function update(Request $request, int $id) public function destroy(int $id) { $prospect = SalesProspect::findOrFail($id); + + // 명함 이미지 삭제 + if ($prospect->business_card_image) { + Storage::disk('public')->delete($prospect->business_card_image); + } + $prospect->delete(); return redirect()->route('sales.prospects.index') ->with('success', '가망고객이 삭제되었습니다.'); } + + /** + * Base64 명함 이미지 저장 + */ + private function saveBusinessCardImage(string $base64Data): ?string + { + // data:image/jpeg;base64,... 형식에서 데이터 추출 + if (preg_match('/^data:image\/(\w+);base64,/', $base64Data, $matches)) { + $extension = $matches[1]; + $base64Data = preg_replace('/^data:image\/\w+;base64,/', '', $base64Data); + } else { + $extension = 'jpg'; + } + + $imageData = base64_decode($base64Data); + if ($imageData === false) { + return null; + } + + $filename = 'business-cards/' . date('Ymd') . '_' . uniqid() . '.' . $extension; + Storage::disk('public')->put($filename, $imageData); + + return $filename; + } } diff --git a/app/Models/Sales/SalesProspect.php b/app/Models/Sales/SalesProspect.php index 77b62036..793978e5 100644 --- a/app/Models/Sales/SalesProspect.php +++ b/app/Models/Sales/SalesProspect.php @@ -22,6 +22,7 @@ class SalesProspect extends Model 'contact_phone', 'email', 'address', + 'business_card_image', 'status', ]; @@ -136,4 +137,24 @@ public function getTotalCommissionAttribute(): float { return $this->products()->sum('commission_amount'); } + + /** + * 명함 이미지 존재 여부 + */ + public function hasBusinessCard(): bool + { + return !empty($this->business_card_image); + } + + /** + * 명함 이미지 URL + */ + public function getBusinessCardUrlAttribute(): ?string + { + if (!$this->hasBusinessCard()) { + return null; + } + + return asset('storage/' . $this->business_card_image); + } } diff --git a/resources/views/sales/prospects/create.blade.php b/resources/views/sales/prospects/create.blade.php index 69baa2a8..aadc2a2b 100644 --- a/resources/views/sales/prospects/create.blade.php +++ b/resources/views/sales/prospects/create.blade.php @@ -111,6 +111,7 @@