474 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			474 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			PHP
		
	
	
	
<?php
 | 
						|
 | 
						|
namespace Modules\Admin\app\Http\Controllers;
 | 
						|
 | 
						|
use App\Http\Controllers\Controller;
 | 
						|
use App\Models\User;
 | 
						|
use App\Services\JiraService;
 | 
						|
use App\Traits\AnalyzeData;
 | 
						|
use App\Traits\HasFilterRequest;
 | 
						|
use App\Traits\HasOrderByRequest;
 | 
						|
use App\Traits\HasSearchRequest;
 | 
						|
use Illuminate\Http\Request;
 | 
						|
use Illuminate\Support\Facades\Mail;
 | 
						|
use Illuminate\Support\Facades\Storage;
 | 
						|
use Illuminate\Support\Facades\Log;
 | 
						|
use Modules\Admin\app\Models\Admin;
 | 
						|
use Modules\Admin\app\Models\Sprint;
 | 
						|
use Modules\Admin\app\Models\UserCriteria;
 | 
						|
use App\Models\Files;
 | 
						|
use App\DataTransferObjects\FileData;
 | 
						|
 | 
						|
class ProfileController extends Controller
 | 
						|
{
 | 
						|
    use HasOrderByRequest;
 | 
						|
    use HasFilterRequest;
 | 
						|
    use HasSearchRequest;
 | 
						|
    use AnalyzeData;
 | 
						|
 | 
						|
    protected $jiraService;
 | 
						|
 | 
						|
    public function __construct(JiraService $jiraService)
 | 
						|
    {
 | 
						|
        $this->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 {
 | 
						|
            // Lấy tất cả users
 | 
						|
            $users = Admin::all();
 | 
						|
            
 | 
						|
            // Lấy files và map theo cấu trúc
 | 
						|
            $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
 | 
						|
                    ];
 | 
						|
                });
 | 
						|
 | 
						|
            // Tạo mảng kết quả với tất cả users, không có file thì mảng rỗng
 | 
						|
            $result = $users->pluck('name')->mapWithKeys(function($userName) use ($files) {
 | 
						|
                $userFiles = $files->where('user_name', $userName)
 | 
						|
                    ->map(function($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']
 | 
						|
                        ];
 | 
						|
                    })->values();
 | 
						|
                    
 | 
						|
                return [$userName => $userFiles];
 | 
						|
            });
 | 
						|
 | 
						|
            return response()->json([
 | 
						|
                'status' => true,
 | 
						|
                'data' => $result
 | 
						|
            ]);
 | 
						|
 | 
						|
        } 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';
 | 
						|
    }
 | 
						|
}
 |