feat: [daily-work-log] 메모/회고 파일 업로드 기능 추가
- 메모, 회고 섹션에 파일 첨부 기능 추가 - 드래그앤드롭 및 클릭 업로드 지원 - 이미지 썸네일 미리보기, 파일 다운로드/삭제 - Boards\File 모델 재사용 (document_type: daily_work_log)
This commit is contained in:
@@ -3,10 +3,13 @@
|
||||
namespace App\Http\Controllers\Finance;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Boards\File;
|
||||
use App\Models\Finance\DailyWorkLog;
|
||||
use App\Models\Finance\DailyWorkLogItem;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DailyWorkLogController extends Controller
|
||||
{
|
||||
@@ -41,6 +44,21 @@ public function show(Request $request): JsonResponse
|
||||
$total = $items->count();
|
||||
$completed = $items->where('is_completed', true)->count();
|
||||
|
||||
$files = File::where('document_type', 'daily_work_log')
|
||||
->where('document_id', $log->id)
|
||||
->whereNull('deleted_at')
|
||||
->get()
|
||||
->map(fn (File $f) => [
|
||||
'id' => $f->id,
|
||||
'field_key' => $f->field_key,
|
||||
'original_name' => $f->original_name,
|
||||
'file_size' => $f->file_size,
|
||||
'formatted_size' => $f->getFormattedSize(),
|
||||
'mime_type' => $f->mime_type,
|
||||
'is_image' => $f->isImage(),
|
||||
'url' => $f->getUrl(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'data' => [
|
||||
@@ -50,6 +68,7 @@ public function show(Request $request): JsonResponse
|
||||
'reflection' => $log->reflection ?? '',
|
||||
'items' => $items->values(),
|
||||
'achievement_rate' => $total > 0 ? round(($completed / $total) * 100, 2) : 0,
|
||||
'files' => $files->values(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
@@ -173,4 +192,101 @@ public function copyFromPrevious(Request $request): JsonResponse
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 업로드 (메모/회고 첨부)
|
||||
*/
|
||||
public function uploadFile(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'log_date' => 'required|date',
|
||||
'field_key' => 'required|in:memo,reflection',
|
||||
'file' => 'required|file|max:10240',
|
||||
]);
|
||||
|
||||
$tenantId = session('selected_tenant_id', 1);
|
||||
|
||||
$log = DailyWorkLog::updateOrCreate(
|
||||
['tenant_id' => $tenantId, 'log_date' => $request->input('log_date')],
|
||||
['created_by' => auth()->id()]
|
||||
);
|
||||
|
||||
$file = $request->file('file');
|
||||
$storedName = Str::uuid().'.'.$file->getClientOriginalExtension();
|
||||
$basePath = "daily-work-log/{$tenantId}/{$log->id}";
|
||||
$filePath = "{$basePath}/{$storedName}";
|
||||
|
||||
Storage::disk('tenant')->put($filePath, file_get_contents($file));
|
||||
|
||||
$record = File::create([
|
||||
'tenant_id' => $tenantId,
|
||||
'is_temp' => false,
|
||||
'file_path' => $filePath,
|
||||
'display_name' => $file->getClientOriginalName(),
|
||||
'stored_name' => $storedName,
|
||||
'original_name' => $file->getClientOriginalName(),
|
||||
'file_name' => $file->getClientOriginalName(),
|
||||
'file_size' => $file->getSize(),
|
||||
'mime_type' => $file->getMimeType(),
|
||||
'file_type' => $this->detectFileType($file->getMimeType()),
|
||||
'field_key' => $request->input('field_key'),
|
||||
'document_type' => 'daily_work_log',
|
||||
'document_id' => $log->id,
|
||||
'uploaded_by' => auth()->id(),
|
||||
'created_by' => auth()->id(),
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'file' => [
|
||||
'id' => $record->id,
|
||||
'field_key' => $record->field_key,
|
||||
'original_name' => $record->original_name,
|
||||
'file_size' => $record->file_size,
|
||||
'formatted_size' => $record->getFormattedSize(),
|
||||
'mime_type' => $record->mime_type,
|
||||
'is_image' => $record->isImage(),
|
||||
'url' => $record->getUrl(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 삭제
|
||||
*/
|
||||
public function deleteFile(int $fileId): JsonResponse
|
||||
{
|
||||
$file = File::where('document_type', 'daily_work_log')->findOrFail($fileId);
|
||||
$file->softDeleteFile(auth()->id());
|
||||
|
||||
return response()->json(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 파일 다운로드
|
||||
*/
|
||||
public function downloadFile(int $fileId)
|
||||
{
|
||||
$file = File::where('document_type', 'daily_work_log')->findOrFail($fileId);
|
||||
|
||||
return $file->download();
|
||||
}
|
||||
|
||||
private function detectFileType(?string $mimeType): string
|
||||
{
|
||||
if (! $mimeType) {
|
||||
return 'other';
|
||||
}
|
||||
if (str_starts_with($mimeType, 'image/')) {
|
||||
return 'image';
|
||||
}
|
||||
if ($mimeType === 'application/pdf') {
|
||||
return 'pdf';
|
||||
}
|
||||
if (str_contains($mimeType, 'spreadsheet') || str_contains($mimeType, 'excel')) {
|
||||
return 'excel';
|
||||
}
|
||||
|
||||
return 'document';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user