jiraService = $jiraService; } public function getProfilesData(Request $request) { $user = auth('admins')->user(); $userEmail = $user->email; $projects = $this->jiraService->getAllProjects(); $startDate = $request->input('fromDate'); $endDate = $request->input('toDate'); $userCriterias = UserCriteria::with([ 'sprint' => function ($query) use ($startDate, $endDate) { if ($startDate && $endDate) { $query->whereBetween('complete_date', [$startDate, $endDate]); } elseif ($startDate) { $query->where('complete_date', '>=', $startDate); } elseif ($endDate) { $query->where('complete_date', '<=', $endDate); } }, 'criteria', ])->where('user_email', $userEmail) ->whereHas('sprint', function ($query) use ($startDate, $endDate) { if ($startDate && $endDate) { $query->whereBetween('complete_date', [$startDate, $endDate]); } elseif ($startDate) { $query->where('complete_date', '>=', $startDate); } elseif ($endDate) { $query->where('complete_date', '<=', $endDate); } }) ->get(); // dd($userCriterias); // Xử lý dữ liệu thành cấu trúc mong muốn $projectsData = $userCriterias->groupBy('sprint.project_id')->map(function ($userCriteriasByProject, $projectId) use ($projects) { $result = self::getProjectById($projects, $projectId); return [ 'name' => $result['name'], 'sprints' => $userCriteriasByProject->groupBy('sprint.id')->map(function ($userCriteriasBySprint) { $sprint = $userCriteriasBySprint->first()->sprint; return [ 'name' => $sprint->name, 'complete_date' => $sprint->complete_date ?? '', 'criterias' => $userCriteriasBySprint->map(function ($userCriteria) { $criteria = $userCriteria->criteria; return [ 'criteria' => $criteria->name, 'note' => $userCriteria->note ?? '', 'createdBy' => $userCriteria->created_by ?? '', // Lấy tên user từ auth 'point' => $userCriteria->point ?? '', ]; }) ]; })->values() ]; })->values(); // Trả về kết quả return AbstractController::ResultSuccess($projectsData); } public function getProjectById($projects, $inputId) { $filteredProjects = array_filter($projects, function ($project) use ($inputId) { return $project['id'] == $inputId; }); return array_values($filteredProjects) ? array_values($filteredProjects)[0] : array_values($filteredProjects); } public function updateProfilesData(Request $request) { $userInfo = auth('admins')->user(); $request->validate([ 'file' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048', // Chỉ chấp nhận file ảnh dưới 2MB ]); $user = User::findOrFail($userInfo->id); if ($user->avatar) { Storage::disk('public')->delete($user->avatar); } $path = $request->file('file')->store('avatars', 'public'); $user->avatar = $path; $user->save(); return AbstractController::ResultSuccess($path); } public function listFiles(Request $request) { // Get the root folder from the input URL $rootFolder = $request->input('root_folder'); // Ensure the root folder is correctly formatted $rootFolder = rtrim($rootFolder, '/') . '/'; // Get all files and directories in the specified root folder $fileList = $this->getDirectoryTree(public_path($rootFolder), env('APP_ENV') === 'local' ? $rootFolder : 'image' . $rootFolder); return response()->json(['data' => $fileList, 'status' => true]); } private function getDirectoryTree($dir, $urlRoot) { $results = []; // Scan the directory for files and folders $files = scandir($dir); foreach ($files as $file) { if ($file !== '.' && $file !== '..') { $filePath = $dir . DIRECTORY_SEPARATOR . $file; $fileUrl = url($urlRoot . $file); if (is_dir($filePath)) { // If it's a directory, recurse into it $results[] = [ 'label' => $file, 'type' => 'directory', 'value' => $fileUrl, 'children' => $this->getDirectoryTree($filePath, $urlRoot . $file . '/') ]; } else { // If it's a file, add it to the list $results[] = [ 'label' => $file, 'type' => 'file', 'value' => $fileUrl ]; } } } return $results; } public function updateProfile(Request $request) { $name = $request->input('name') ?? auth('admins')->user()->name; // Validate the incoming files $request->validate([ 'files.*' => 'required|file|mimes:jpg,png,jpeg,pdf,doc,docx,xlsx,xls,csv|max:5120', // Adjust file types and size limit as needed ]); $uploadedFiles = []; $baseDirectory = 'profiles/' . $name; $othersDirectory = $baseDirectory . '/others'; // Check if the base directory exists, if not create it if (!Storage::disk('public')->exists($baseDirectory)) { Storage::disk('public')->makeDirectory($baseDirectory); } // Check if the "others" directory exists, if not create it if (!Storage::disk('public')->exists($othersDirectory)) { Storage::disk('public')->makeDirectory($othersDirectory); } $adminEmails = Admin::where('permission', 'like', '%admin%')->pluck('email')->toArray(); $currentUser = auth('admins')->user(); if ($request->hasFile('files')) { foreach ($request->file('files') as $file) { // Store the file and get its path $originalFilename = $file->getClientOriginalName(); if (strpos($originalFilename, '__') === 0) { // Store the file in the "others" directory $path = $file->storeAs($othersDirectory, $originalFilename, 'public'); } else { // Store the file in the base directory $path = $file->storeAs($baseDirectory, $originalFilename, 'public'); } $uploadedFiles[] = $path; // Tạo URL đầy đủ cho file $fileUrl = (env('APP_ENV') === 'prod' || env('APP_ENV') === 'production') ? env('APP_URL') . '/image/' . str_replace('/storage/', '', Storage::url($path)) : env('APP_URL') . str_replace('/storage/', '', Storage::url($path)); // // Gửi email thông báo cho admin // foreach ($adminEmails as $adminEmail) { // $admin = Admin::where('email', $adminEmail)->first(); // if ($admin) { // $this->sendFileUploadNotification( // $admin, // "File {$originalFilename} đã được tải lên bởi {$currentUser->name}", // $fileUrl, // "[APAC Tech] {$currentUser->name} - Đã tải lên file mới" // ); // } // } // // Gửi email xác nhận cho người tải lên // $this->sendFileUploadNotification( // $currentUser, // "Bạn đã tải lên file {$originalFilename} thành công", // $fileUrl, // "[APAC Tech] {$currentUser->name} - Tải file thành công" // ); } } return response()->json([ 'status' => true, 'message' => 'Files uploaded successfully', 'files' => $uploadedFiles, ]); } public function removeFile(Request $request) { // Validate that the file URL is provided in the request $request->validate([ 'file_url' => 'required|string', ]); // Get the full file URL from the request $fileUrl = $request->input('file_url'); // Parse the file path from the URL (remove the base URL part) $storagePath = parse_url($fileUrl, PHP_URL_PATH); // Extract the path part of the URL $filePath = str_replace(env('APP_ENV') === 'local' ? '/storage/' : '/image/storage/', '', $storagePath); // Remove "/storage/" to get the actual file path // Check if the file exists before attempting to delete it if (Storage::disk('public')->exists($filePath)) { // Delete the file Storage::disk('public')->delete($filePath); return response()->json([ 'status' => true, 'message' => 'File deleted successfully', ]); } return response()->json([ 'status' => false, 'message' => 'File not found', ], 404); } public function sendFileUploadNotification($user, $description, $url, $subject, $note) { try { // Gửi email bất đồng bộ không cần job dispatch(function() use ($user, $description, $url, $subject, $note) { Mail::send('emails.file_upload_notification', [ 'user' => $user, 'description' => $description, 'url' => $url, 'note' => $note ], function ($message) use ($user, $subject) { $message->to($user->email) ->subject($subject); }); })->afterResponse(); return true; } catch (\Exception $e) { Log::error('Error dispatching file upload notification email: ' . $e->getMessage()); return false; } } public function uploadFiles(Request $request) { try { $request->validate([ 'file' => 'required|file|mimes:jpg,jpeg,png,pdf,doc,docx,xls,xlsx,csv|max:5120', 'name' => 'required|string|max:255', 'description' => 'nullable|string', 'user_name' => 'required|string|max:255' ]); $file = $request->file('file'); $user = auth('admins')->user(); // Tạo thư mục cho user nếu chưa tồn tại $userFolder = 'files/' . $request->user_name; if (!Storage::disk('public')->exists($userFolder)) { Storage::disk('public')->makeDirectory($userFolder); } $path = $file->store($userFolder, 'public'); $fileRecord = Files::create([ 'name' => $request->name, 'url' => $path, 'type' => $this->getFileType($file->getClientOriginalName()), 'description' => $request->description, 'user_id' => Admin::where('name', $request->user_name)->first()->id ]); $currentUser = Admin::where('name', $request->user_name)->first(); // Gửi email thông báo cho người upload $fileUrl = (env('APP_ENV') === 'prod' || env('APP_ENV') === 'production') ? env('APP_URL') . '/image' . Storage::url($path) : env('APP_URL') . Storage::url($path); $this->sendFileUploadNotification( $user, 'Bạn đã tải lên file "' . $request->name . '" thành công', $fileUrl, "[APAC Tech] {$currentUser->name} - Đã tải lên file mới", $request->description ?? 'No description' ); // Gửi email thông báo cho tất cả admin khác $otherAdmins = Admin::where('permission', 'like', '%admin%')->get(); foreach ($otherAdmins as $admin) { $this->sendFileUploadNotification( $admin, 'File "' . $request->name . '" đã được tải lên bởi ' . $user->name, $fileUrl, "[APAC Tech] {$currentUser->name} - Đã tải lên file mới", $request->description ?? 'No description' ); } return response()->json([ 'status' => true, 'message' => 'File uploaded successfully', 'data' => [ 'id' => $fileRecord->id, 'name' => $fileRecord->name, 'url' => Storage::url($path), 'type' => $fileRecord->type, 'description' => $fileRecord->description ] ]); } catch (\Exception $e) { return response()->json([ 'status' => false, 'message' => $e->getMessage() ], 500); } } public function getFiles() { try { $files = Files::with('user')->get() ->map(function($file) { return [ 'id' => $file->id, 'name' => $file->name, 'url' => Storage::url($file->url), 'type' => $file->type, 'description' => $file->description, 'created_at' => $file->created_at, 'user_id' => $file->user_id, 'user_name' => $file->user->name ]; }); // Gom nhóm files theo tên user $groupedFiles = $files->groupBy('user_name') ->map(function($files) { return $files->map(function(array $file) { return (object)[ 'id' => $file['id'], 'name' => $file['name'], 'url' => $file['url'], 'type' => $file['type'], 'description' => $file['description'], 'created_at' => $file['created_at'], 'user_id' => $file['user_id'] ]; }); }); return response()->json([ 'status' => true, 'data' => $groupedFiles ]); } catch (\Exception $e) { return response()->json([ 'status' => false, 'message' => $e->getMessage() ], 500); } } public function deleteFile($id) { try { $file = Files::findOrFail($id); $user = auth('admins')->user(); if ($file->user_id !== $user->id) { return response()->json([ 'status' => false, 'message' => 'Unauthorized' ], 403); } Storage::disk('public')->delete($file->url); $file->delete(); return response()->json([ 'status' => true, 'message' => 'File deleted successfully' ]); } catch (\Exception $e) { return response()->json([ 'status' => false, 'message' => $e->getMessage() ], 500); } } private function getFileType($filename) { $extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); $typeMap = [ 'pdf' => 'document', 'doc' => 'document', 'docx' => 'document', 'jpg' => 'image', 'jpeg' => 'image', 'png' => 'image', 'xls' => 'spreadsheet', 'xlsx' => 'spreadsheet', 'csv' => 'spreadsheet' ]; return $typeMap[$extension] ?? 'other'; } }