Files
usher-manage-stack/app/Http/Controllers/PublicDocumentController.php
Gbanyan 642b879dd4 Add membership fee system with disability discount and fix document permissions
Features:
- Implement two fee types: entrance fee and annual fee (both NT$1,000)
- Add 50% discount for disability certificate holders
- Add disability certificate upload in member profile
- Integrate disability verification into cashier approval workflow
- Add membership fee settings in system admin

Document permissions:
- Fix hard-coded role logic in Document model
- Use permission-based authorization instead of role checks

Additional features:
- Add announcements, general ledger, and trial balance modules
- Add income management and accounting entries
- Add comprehensive test suite with factories
- Update UI translations to Traditional Chinese

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-01 09:56:01 +08:00

180 lines
5.4 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->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->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"');
}
}