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>
This commit is contained in:
2025-12-01 09:56:01 +08:00
parent 83ce1f7fc8
commit 642b879dd4
207 changed files with 19487 additions and 3048 deletions

View File

@@ -1,6 +1,6 @@
<x-app-layout>
<x-slot name="header">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
文件中心
</h2>
</x-slot>
@@ -8,41 +8,41 @@
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8 space-y-6">
<!-- Categories -->
<div class="bg-white shadow sm:rounded-lg p-6">
<h3 class="text-lg font-medium text-gray-900 mb-4">文件類別</h3>
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg p-6">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100 mb-4">文件類別</h3>
<div class="grid grid-cols-2 gap-4 md:grid-cols-3 lg:grid-cols-6">
<a href="{{ route('documents.index') }}"
class="flex flex-col items-center p-4 border rounded-lg hover:bg-gray-50 transition
{{ !request('category') ? 'border-indigo-500 bg-indigo-50' : 'border-gray-200' }}">
class="flex flex-col items-center p-4 border rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition
{{ !request('category') ? 'border-indigo-500 bg-indigo-50 dark:bg-indigo-900/30' : 'border-gray-200 dark:border-gray-700' }}">
<span class="text-3xl mb-2">📚</span>
<span class="text-sm font-medium text-gray-900">全部文件</span>
<span class="text-xs text-gray-500 mt-1">{{ $documents->total() }}</span>
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">全部文件</span>
<span class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ $documents->total() }}</span>
</a>
@foreach($categories as $category)
<a href="{{ route('documents.index', ['category' => $category->id]) }}"
class="flex flex-col items-center p-4 border rounded-lg hover:bg-gray-50 transition
{{ request('category') == $category->id ? 'border-indigo-500 bg-indigo-50' : 'border-gray-200' }}">
class="flex flex-col items-center p-4 border rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition
{{ request('category') == $category->id ? 'border-indigo-500 bg-indigo-50 dark:bg-indigo-900/30' : 'border-gray-200 dark:border-gray-700' }}">
<span class="text-3xl mb-2">{{ $category->getIconDisplay() }}</span>
<span class="text-sm font-medium text-gray-900 text-center">{{ $category->name }}</span>
<span class="text-xs text-gray-500 mt-1">{{ $category->active_documents_count }}</span>
<span class="text-sm font-medium text-gray-900 dark:text-gray-100 text-center">{{ $category->name }}</span>
<span class="text-xs text-gray-500 dark:text-gray-400 mt-1">{{ $category->active_documents_count }}</span>
</a>
@endforeach
</div>
</div>
<!-- Search -->
<div class="bg-white shadow sm:rounded-lg p-6">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg p-6">
<form method="GET" action="{{ route('documents.index') }}" class="flex gap-4">
<input type="hidden" name="category" value="{{ request('category') }}">
<div class="flex-1">
<input type="text" name="search" value="{{ request('search') }}" placeholder="搜尋文件標題或說明..."
class="block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
class="block w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
</div>
<button type="submit" class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-6 py-2 text-sm font-medium text-white hover:bg-indigo-700">
<button type="submit" class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-6 py-2 text-sm font-medium text-white hover:bg-indigo-700 dark:hover:bg-indigo-500">
搜尋
</button>
@if(request('search') || request('category'))
<a href="{{ route('documents.index') }}" class="inline-flex items-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50">
<a href="{{ route('documents.index') }}" class="inline-flex items-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600">
清除
</a>
@endif
@@ -52,7 +52,7 @@
<!-- Documents List -->
<div class="space-y-4">
@forelse($documents as $document)
<div class="bg-white shadow sm:rounded-lg hover:shadow-md transition">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg hover:shadow-md transition">
<div class="px-6 py-5">
<div class="flex items-start">
<div class="flex-shrink-0 text-4xl mr-4">
@@ -61,15 +61,15 @@
<div class="flex-1 min-w-0">
<div class="flex items-start justify-between">
<div class="flex-1">
<h3 class="text-lg font-medium text-gray-900">
<a href="{{ route('documents.public.show', $document->public_uuid) }}" class="hover:text-indigo-600">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
<a href="{{ route('documents.public.show', $document->public_uuid) }}" class="hover:text-indigo-600 dark:hover:text-indigo-400">
{{ $document->title }}
</a>
</h3>
@if($document->description)
<p class="mt-1 text-sm text-gray-500">{{ $document->description }}</p>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ $document->description }}</p>
@endif
<div class="mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500">
<div class="mt-2 flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-gray-500 dark:text-gray-400">
<span class="inline-flex items-center">
{{ $document->category->icon }} {{ $document->category->name }}
</span>
@@ -91,11 +91,11 @@
</div>
<div class="ml-6 flex flex-col space-y-2">
<a href="{{ route('documents.public.show', $document->public_uuid) }}"
class="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700">
class="inline-flex items-center justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-700 dark:hover:bg-indigo-500">
檢視
</a>
<a href="{{ route('documents.public.download', $document->public_uuid) }}"
class="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50">
class="inline-flex items-center justify-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600">
下載
</a>
</div>
@@ -105,16 +105,16 @@
</div>
</div>
@empty
<div class="bg-white shadow sm:rounded-lg">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-6 py-12 text-center">
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">找不到文件</h3>
<p class="mt-1 text-sm text-gray-500">目前沒有符合條件的文件</p>
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">找不到文件</h3>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">目前沒有符合條件的文件</p>
@if(request('search') || request('category'))
<div class="mt-6">
<a href="{{ route('documents.index') }}" class="text-indigo-600 hover:text-indigo-900">
<a href="{{ route('documents.index') }}" class="text-indigo-600 hover:text-indigo-900 dark:text-indigo-400 dark:hover:text-indigo-300">
瀏覽所有文件
</a>
</div>
@@ -126,7 +126,7 @@
<!-- Pagination -->
@if($documents->hasPages())
<div class="bg-white shadow sm:rounded-lg p-6">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg p-6">
{{ $documents->links() }}
</div>
@endif

View File

@@ -1,10 +1,10 @@
<x-app-layout>
<x-slot name="header">
<div class="flex items-center justify-between">
<h2 class="text-xl font-semibold leading-tight text-gray-800">
<h2 class="text-xl font-semibold leading-tight text-gray-800 dark:text-gray-200">
{{ $document->title }}
</h2>
<a href="{{ route('documents.index') }}" class="text-sm text-gray-600 hover:text-gray-900">
<a href="{{ route('documents.index') }}" class="text-sm text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-200">
返回文件中心
</a>
</div>
@@ -13,32 +13,32 @@
<div class="py-12">
<div class="mx-auto max-w-4xl sm:px-6 lg:px-8 space-y-6">
<!-- Document Header -->
<div class="bg-white shadow sm:rounded-lg">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-6 py-8">
<div class="flex items-start">
<div class="flex-shrink-0 text-6xl mr-6">
{{ $document->currentVersion->getFileIcon() }}
</div>
<div class="flex-1">
<h1 class="text-2xl font-bold text-gray-900">{{ $document->title }}</h1>
<h1 class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ $document->title }}</h1>
@if($document->document_number)
<p class="mt-1 text-sm text-gray-500">文號:{{ $document->document_number }}</p>
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">文號:{{ $document->document_number }}</p>
@endif
@if($document->description)
<p class="mt-3 text-gray-700">{{ $document->description }}</p>
<p class="mt-3 text-gray-700 dark:text-gray-300">{{ $document->description }}</p>
@endif
<div class="mt-4 flex flex-wrap items-center gap-4">
<span class="inline-flex items-center rounded-full px-3 py-1 text-sm font-medium
@if($document->access_level === 'public') bg-green-100 text-green-800
@elseif($document->access_level === 'members') bg-blue-100 text-blue-800
@else bg-gray-100 text-gray-800
@if($document->access_level === 'public') bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200
@elseif($document->access_level === 'members') bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200
@else bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200
@endif">
{{ $document->getAccessLevelLabel() }}
</span>
<span class="text-sm text-gray-500">
<span class="text-sm text-gray-500 dark:text-gray-400">
{{ $document->category->icon }} {{ $document->category->name }}
</span>
<span class="text-sm text-gray-500">
<span class="text-sm text-gray-500 dark:text-gray-400">
📅 {{ $document->created_at->format('Y年m月d日') }}
</span>
</div>
@@ -48,40 +48,40 @@
</div>
<!-- Current Version Info -->
<div class="bg-white shadow sm:rounded-lg">
<div class="px-6 py-5 border-b border-gray-200">
<h3 class="text-lg font-medium text-gray-900">當前版本</h3>
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-6 py-5 border-b border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">當前版本</h3>
</div>
<div class="px-6 py-5">
<dl class="grid grid-cols-1 gap-x-4 gap-y-6 sm:grid-cols-2">
<div>
<dt class="text-sm font-medium text-gray-500">版本號</dt>
<dd class="mt-1 text-sm text-gray-900">v{{ $document->currentVersion->version_number }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">版本號</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">v{{ $document->currentVersion->version_number }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">檔案名稱</dt>
<dd class="mt-1 text-sm text-gray-900">{{ $document->currentVersion->original_filename }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">檔案名稱</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $document->currentVersion->original_filename }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">檔案大小</dt>
<dd class="mt-1 text-sm text-gray-900">{{ $document->currentVersion->getFileSizeHuman() }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">檔案大小</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $document->currentVersion->getFileSizeHuman() }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">上傳時間</dt>
<dd class="mt-1 text-sm text-gray-900">{{ $document->currentVersion->uploaded_at->format('Y-m-d H:i') }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">上傳時間</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $document->currentVersion->uploaded_at->format('Y-m-d H:i') }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">上傳者</dt>
<dd class="mt-1 text-sm text-gray-900">{{ $document->currentVersion->uploadedBy->name }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">上傳者</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $document->currentVersion->uploadedBy->name }}</dd>
</div>
<div>
<dt class="text-sm font-medium text-gray-500">檔案格式</dt>
<dd class="mt-1 text-sm text-gray-900">{{ strtoupper($document->currentVersion->getFileExtension()) }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">檔案格式</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ strtoupper($document->currentVersion->getFileExtension()) }}</dd>
</div>
@if($document->currentVersion->version_notes)
<div class="sm:col-span-2">
<dt class="text-sm font-medium text-gray-500">版本說明</dt>
<dd class="mt-1 text-sm text-gray-900">{{ $document->currentVersion->version_notes }}</dd>
<dt class="text-sm font-medium text-gray-500 dark:text-gray-400">版本說明</dt>
<dd class="mt-1 text-sm text-gray-900 dark:text-gray-100">{{ $document->currentVersion->version_notes }}</dd>
</div>
@endif
</dl>
@@ -90,30 +90,30 @@
@if($document->expires_at)
<div class="mt-4">
@if($document->isExpired())
<div class="rounded-md bg-red-50 p-3">
<div class="rounded-md bg-red-50 dark:bg-red-900/30 p-3">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-red-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<svg class="h-5 w-5 text-red-400 dark:text-red-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-red-800">
<p class="text-sm font-medium text-red-800 dark:text-red-200">
此文件已於 {{ $document->expires_at->format('Y年m月d日') }} 過期
</p>
</div>
</div>
</div>
@elseif($document->isExpiringSoon(30))
<div class="rounded-md bg-yellow-50 p-3">
<div class="rounded-md bg-yellow-50 dark:bg-yellow-900/30 p-3">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-yellow-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<svg class="h-5 w-5 text-yellow-400 dark:text-yellow-300" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
</svg>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-yellow-800">
<p class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
此文件將於 {{ $document->expires_at->format('Y年m月d日') }} 過期
</p>
</div>
@@ -125,14 +125,14 @@
<div class="mt-6 flex flex-wrap gap-4">
<a href="{{ route('documents.public.download', $document->public_uuid) }}"
class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-6 py-3 text-base font-medium text-white hover:bg-indigo-700">
class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-6 py-3 text-base font-medium text-white hover:bg-indigo-700 dark:hover:bg-indigo-500">
<svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
</svg>
下載文件
</a>
<button onclick="copyToClipboard('{{ $document->getPublicUrl() }}')"
class="inline-flex items-center rounded-md border border-gray-300 bg-white px-6 py-3 text-base font-medium text-gray-700 hover:bg-gray-50">
class="inline-flex items-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-6 py-3 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
<svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
</svg>
@@ -140,7 +140,7 @@
</button>
@if(settings()->isFeatureEnabled('qr_codes') && (!auth()->user() || auth()->user()->can('use_qr_codes')))
<a href="{{ route('documents.public.qrcode', $document->public_uuid) }}"
class="inline-flex items-center rounded-md border border-gray-300 bg-white px-6 py-3 text-base font-medium text-gray-700 hover:bg-gray-50">
class="inline-flex items-center rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 px-6 py-3 text-base font-medium text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-600">
<svg class="-ml-1 mr-2 h-5 w-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v1m6 11h2m-6 0h-2v4m0-11v3m0 0h.01M12 12h4.01M16 20h4M4 12h4m12 0h.01M5 8h2a1 1 0 001-1V5a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1zm12 0h2a1 1 0 001-1V5a1 1 0 00-1-1h-2a1 1 0 00-1 1v2a1 1 0 001 1zM5 20h2a1 1 0 001-1v-2a1 1 0 00-1-1H5a1 1 0 00-1 1v2a1 1 0 001 1z" />
</svg>
@@ -153,40 +153,40 @@
<!-- Version History -->
@if($document->versions->count() > 1)
<div class="bg-white shadow sm:rounded-lg">
<div class="px-6 py-5 border-b border-gray-200">
<h3 class="text-lg font-medium text-gray-900">版本歷史</h3>
<p class="mt-1 text-sm text-gray-600"> {{ $document->version_count }} 個版本</p>
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-6 py-5 border-b border-gray-200 dark:border-gray-700">
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">版本歷史</h3>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400"> {{ $document->version_count }} 個版本</p>
</div>
<div class="px-6 py-5">
<ul class="space-y-4">
@foreach($document->versions as $version)
<li class="flex items-start {{ $version->is_current ? 'bg-indigo-50 -mx-6 px-6 py-4' : '' }}">
<li class="flex items-start {{ $version->is_current ? 'bg-indigo-50 dark:bg-indigo-900/30 -mx-6 px-6 py-4' : '' }}">
<div class="flex-shrink-0 text-2xl mr-4">
{{ $version->getFileIcon() }}
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center space-x-2">
<span class="text-sm font-medium text-gray-900">版本 {{ $version->version_number }}</span>
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">版本 {{ $version->version_number }}</span>
@if($version->is_current)
<span class="inline-flex items-center rounded-full bg-green-100 px-2.5 py-0.5 text-xs font-medium text-green-800">
<span class="inline-flex items-center rounded-full bg-green-100 dark:bg-green-900 px-2.5 py-0.5 text-xs font-medium text-green-800 dark:text-green-200">
當前版本
</span>
@endif
</div>
<p class="mt-1 text-sm text-gray-500">
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
{{ $version->original_filename }} · {{ $version->getFileSizeHuman() }}
</p>
<p class="mt-1 text-xs text-gray-500">
<p class="mt-1 text-xs text-gray-500 dark:text-gray-400">
{{ $version->uploaded_at->format('Y-m-d H:i') }} · {{ $version->uploadedBy->name }}
</p>
@if($version->version_notes)
<p class="mt-2 text-sm text-gray-600">{{ $version->version_notes }}</p>
<p class="mt-2 text-sm text-gray-600 dark:text-gray-300">{{ $version->version_notes }}</p>
@endif
</div>
<div class="ml-4">
<a href="{{ route('documents.public.download-version', [$document->public_uuid, $version->id]) }}"
class="text-sm text-indigo-600 hover:text-indigo-900">
class="text-sm text-indigo-600 dark:text-indigo-400 hover:text-indigo-900 dark:hover:text-indigo-300">
下載
</a>
</div>
@@ -198,31 +198,31 @@
@endif
<!-- File Integrity Info -->
<div class="bg-gray-50 shadow sm:rounded-lg">
<div class="bg-gray-50 dark:bg-gray-700 shadow sm:rounded-lg">
<div class="px-6 py-4">
<div class="flex items-center text-sm text-gray-600">
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
<svg class="mr-2 h-5 w-5 text-green-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
<span>
此文件經過完整性驗證,確保內容未被篡改。檔案雜湊:
<code class="ml-1 px-2 py-1 bg-gray-100 rounded text-xs">{{ substr($document->currentVersion->file_hash, 0, 16) }}...</code>
<code class="ml-1 px-2 py-1 bg-gray-100 dark:bg-gray-900 rounded text-xs">{{ substr($document->currentVersion->file_hash, 0, 16) }}...</code>
</span>
</div>
</div>
</div>
<!-- Statistics -->
<div class="bg-white shadow sm:rounded-lg">
<div class="bg-white dark:bg-gray-800 shadow sm:rounded-lg">
<div class="px-6 py-5">
<div class="grid grid-cols-2 gap-4 text-center">
<div>
<div class="text-3xl font-bold text-indigo-600">{{ $document->view_count }}</div>
<div class="mt-1 text-sm text-gray-500">檢視次數</div>
<div class="text-3xl font-bold text-indigo-600 dark:text-indigo-400">{{ $document->view_count }}</div>
<div class="mt-1 text-sm text-gray-500 dark:text-gray-400">檢視次數</div>
</div>
<div>
<div class="text-3xl font-bold text-green-600">{{ $document->download_count }}</div>
<div class="mt-1 text-sm text-gray-500">下載次數</div>
<div class="text-3xl font-bold text-green-600 dark:text-green-400">{{ $document->download_count }}</div>
<div class="mt-1 text-sm text-gray-500 dark:text-gray-400">下載次數</div>
</div>
</div>
</div>