180 lines
5.5 KiB
PHP
180 lines
5.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Document;
|
|
use App\Models\DocumentCategory;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class PublicDocumentController extends Controller
|
|
{
|
|
/**
|
|
* Display the document library (public + member access)
|
|
*/
|
|
public function index(Request $request)
|
|
{
|
|
$query = Document::with(['category', 'currentVersion'])
|
|
->where('status', 'active');
|
|
|
|
// Filter based on user's access level
|
|
$user = auth()->user();
|
|
if (!$user) {
|
|
// Only public documents for guests
|
|
$query->where('access_level', 'public');
|
|
} elseif (!$user->is_admin && !$user->hasRole('admin')) {
|
|
// Members can see public + members-only
|
|
$query->whereIn('access_level', ['public', 'members']);
|
|
}
|
|
// Admins can see all documents
|
|
|
|
// Filter by category
|
|
if ($request->filled('category')) {
|
|
$query->where('document_category_id', $request->category);
|
|
}
|
|
|
|
// Search
|
|
if ($request->filled('search')) {
|
|
$search = $request->search;
|
|
$query->where(function($q) use ($search) {
|
|
$q->where('title', 'like', "%{$search}%")
|
|
->orWhere('description', 'like', "%{$search}%");
|
|
});
|
|
}
|
|
|
|
$documents = $query->orderBy('created_at', 'desc')->paginate(20);
|
|
|
|
// Get categories with document counts (based on user's access)
|
|
$categories = DocumentCategory::withCount([
|
|
'activeDocuments' => function($query) use ($user) {
|
|
if (!$user) {
|
|
$query->where('access_level', 'public');
|
|
} elseif (!$user->is_admin && !$user->hasRole('admin')) {
|
|
$query->whereIn('access_level', ['public', 'members']);
|
|
}
|
|
}
|
|
])->orderBy('sort_order')->get();
|
|
|
|
return view('documents.index', compact('documents', 'categories'));
|
|
}
|
|
|
|
/**
|
|
* Show a document via its public UUID
|
|
*/
|
|
public function show(string $uuid)
|
|
{
|
|
$document = Document::where('public_uuid', $uuid)
|
|
->where('status', 'active')
|
|
->with(['category', 'currentVersion', 'versions.uploadedBy'])
|
|
->firstOrFail();
|
|
|
|
// Check access permission
|
|
$user = auth()->user();
|
|
if (!$document->canBeViewedBy($user)) {
|
|
if (!$user) {
|
|
return redirect()->route('login')->with('error', '請先登入以檢視此文件');
|
|
}
|
|
abort(403, '您沒有權限檢視此文件');
|
|
}
|
|
|
|
// Log access
|
|
$document->logAccess('view', $user);
|
|
|
|
return view('documents.show', compact('document'));
|
|
}
|
|
|
|
/**
|
|
* Download the current version of a document
|
|
*/
|
|
public function download(string $uuid)
|
|
{
|
|
$document = Document::where('public_uuid', $uuid)
|
|
->where('status', 'active')
|
|
->firstOrFail();
|
|
|
|
// Check access permission
|
|
$user = auth()->user();
|
|
if (!$document->canBeViewedBy($user)) {
|
|
if (!$user) {
|
|
return redirect()->route('login')->with('error', '請先登入以下載此文件');
|
|
}
|
|
abort(403, '您沒有權限下載此文件');
|
|
}
|
|
|
|
$currentVersion = $document->currentVersion;
|
|
if (!$currentVersion || !$currentVersion->fileExists()) {
|
|
abort(404, '檔案不存在');
|
|
}
|
|
|
|
// Log access
|
|
$document->logAccess('download', $user);
|
|
|
|
return Storage::disk('private')->download(
|
|
$currentVersion->file_path,
|
|
$currentVersion->original_filename
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Download a specific version (if user has access)
|
|
*/
|
|
public function downloadVersion(string $uuid, int $versionId)
|
|
{
|
|
$document = Document::where('public_uuid', $uuid)
|
|
->where('status', 'active')
|
|
->firstOrFail();
|
|
|
|
// Check access permission
|
|
$user = auth()->user();
|
|
if (!$document->canBeViewedBy($user)) {
|
|
abort(403, '您沒有權限下載此文件');
|
|
}
|
|
|
|
$version = $document->versions()->findOrFail($versionId);
|
|
|
|
if (!$version->fileExists()) {
|
|
abort(404, '檔案不存在');
|
|
}
|
|
|
|
// Log access
|
|
$document->logAccess('download', $user);
|
|
|
|
return Storage::disk('private')->download(
|
|
$version->file_path,
|
|
$version->original_filename
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Generate and download QR code for document
|
|
*/
|
|
public function downloadQRCode(string $uuid)
|
|
{
|
|
// Check if QR code feature is enabled
|
|
$settings = app(\App\Services\SettingsService::class);
|
|
if (!$settings->isFeatureEnabled('qr_codes')) {
|
|
abort(404, 'QR Code 功能未啟用');
|
|
}
|
|
|
|
// Check user permission
|
|
$user = auth()->user();
|
|
if ($user && !$user->can('use_qr_codes')) {
|
|
abort(403, '您沒有使用 QR Code 功能的權限');
|
|
}
|
|
|
|
$document = Document::where('public_uuid', $uuid)->firstOrFail();
|
|
|
|
// Check document access
|
|
if (!$document->canBeViewedBy($user)) {
|
|
abort(403);
|
|
}
|
|
|
|
// Use default size from system settings
|
|
$qrCode = $document->generateQRCodePNG();
|
|
|
|
return response($qrCode, 200)
|
|
->header('Content-Type', 'image/png')
|
|
->header('Content-Disposition', 'attachment; filename="qrcode-' . $document->id . '.png"');
|
|
}
|
|
}
|