@push('styles') @endpush
BuildHub / Marketing

Danh sách ứng dụng & APK

Tải bản mới nhất hoặc mở lại phiên bản cũ của mọi ứng dụng công ty.

{{-- Quyền chỉ xem và tải xuống --}}
▦
{{ count($marketingApps ?? []) }}Ứng dụng

Danh sách ứng dụng

Bản mới upload có thể chưa Pass; bản đã Public được đánh dấu riêng.
@php $filter = request('filter') ?? (request('status') ?? 'all'); $searchQ = strtolower(trim(request('q') ?? '')); $apps = collect($marketingApps ?? []); if ($searchQ !== '') { $apps = $apps->filter(function ($app) use ($searchQ) { $allTesters = $app->versions->flatMap->reports ->pluck('tester.name') ->filter() ->unique() ->implode(' '); return str_contains(strtolower($app->name), $searchQ) || str_contains(strtolower($app->st_app ?? ''), $searchQ) || str_contains(strtolower($app->package), $searchQ) || str_contains(strtolower($allTesters), $searchQ); }); } if ($filter === 'published') { $apps = $apps->filter(fn($app) => $app->stableRelease !== null); } elseif ($filter === 'passed') { $apps = $apps->filter(fn($app) => $app->latestRelease?->test_status === 'passed'); } elseif ($filter === 'pending') { $apps = $apps->filter( fn($app) => $app->latestRelease?->test_status !== 'passed' && !$app->latestRelease?->isPublished(), ); } @endphp
@forelse($apps as $app) @php $latest = $app->latestRelease; $stable = $app->stableRelease; $latestBuild = $app->latestBuild; $noads = $app->noadsRelease ?? null; $state = $latest?->published_at ? 'published' : $latest?->test_status ?? 'waiting'; $labels = [ 'published' => 'Đã Public', 'passed' => 'Đã Pass', 'waiting' => 'Chờ test', 'testing' => 'Đang test', 'failed' => 'Cần sửa', ]; $colors = [ '#5367e9,#987cf0', '#13a59f,#67c3b3', '#ea8a5d,#f2bb79', '#6578a9,#9eabd1', '#a66dd3,#d08ed8', '#378dc2,#82b7e9', ]; // Thông tin Tester $testedBy = $latest?->reports?->pluck('tester.name')->filter()->unique()->implode(', '); if (empty($testedBy)) { $testedBy = $app->versions->flatMap->reports ->pluck('tester.name') ->filter() ->unique() ->implode(', '); } $assignedTesters = ''; if (!empty($app->tester_ids) && isset($testerUsers)) { $assignedTesters = collect($app->tester_ids) ->map(fn($uid) => $testerUsers[$uid] ?? null) ->filter() ->unique() ->implode(', '); } $appTester = $testedBy ?: $assignedTesters; @endphp
@if (!empty($app->package))
{{ $app->name }}
{{ mb_strtoupper(mb_substr($app->name, 0, 1)) }}
@else
{{ mb_strtoupper(mb_substr($app->name, 0, 1)) }}
@endif
{{ $app->st_app ? $app->st_app . ' - ' : '' }}{{ $app->name }}
{{ $app->package }}
{{ $app->versionCount }} phiên bản{{ $app->buildCount }} file APKCập nhật: {{ $latestBuild?->created_at?->format('d/m/Y H:i') ?? '—' }} @if ($appTester) Tester: {{ $appTester }} @endif
@if ($latest) @endif @if ($latestBuild) ↓ Tải mới nhất @endif
⚡ APK mới upload gần nhất
{{ $latest ? 'v' . $latest->version_name : '—' }} @if ($latestBuild) Build #{{ $latestBuild->revision }} @endif {{ $labels[$state] ?? $state }} @if ($latest) @php $latestTester = $latest->reports ->pluck('tester.name') ->filter() ->unique() ->implode(', ') ?: $assignedTesters; @endphp @if ($latestTester) Tester: {{ $latestTester }} @endif @endif
{{ $latestBuild ? number_format($latestBuild->file_size / 1048576, 1) . ' MB' : 'Chưa có file' }} · {{ $latestBuild?->created_at?->format('d/m/Y H:i') ?? '—' }}
Bản không có quảng cáo
@if ($noads) @php $noadsExt = $noads->noads_apk_path ? 'APK' : 'AAB'; @endphp
v{{ $noads->version_name }} No-Ads ↓ Tải {{ $noadsExt }}
{{ $noadsExt }} No-Ads @if ($noads->noads_uploaded_at) · {{ $noads->noads_uploaded_at->format('d/m/Y H:i') }} @endif
@else
Chưa có bản No-Ads
Developer chưa upload bản không có quảng cáo.
@endif
Xem toàn bộ {{ $app->versionCount }} phiên bản và lịch sử build @foreach ($app->versions as $release) @php $rstate = $release->published_at ? 'published' : $release->test_status; $relTester = $release->reports ->pluck('tester.name') ->filter() ->unique() ->implode(', ') ?: $assignedTesters; @endphp
v{{ $release->version_name }} Code {{ $release->version_code }}{{ strtoupper($release->channel ?? ($release->app_android_id ? 'Android' : 'iOS')) }}{{ $labels[$rstate] ?? $rstate }} @if ($relTester) Tester: {{ $relTester }} @endif
{{ $release->builds->count() }} lần upload · Build mới nhất #{{ $release->builds->first()?->revision ?? $release->current_revision }}
Xem và tải từng bản APK trong v{{ $release->version_name }} ▾ @foreach ($release->builds as $build)
Build #{{ $build->revision }} @if ($loop->first) · Bản mới của version này @endif
{{ $build->original_name }} · {{ number_format($build->file_size / 1048576, 1) }} MB · {{ $build->created_at?->format('d/m/Y H:i') }}
@if ($build->notes)
{{ \Illuminate\Support\Str::limit($build->notes, 180) }}
@endif
↓ Tải APK
@endforeach
@if ($release->builds->first()) ↓ Tải v{{ $release->version_name }} @endif
@endforeach
@empty
Không có ứng dụng nào phù hợp. Thử tìm theo tên hoặc package khác.
@endforelse
{{--
{{ $page->total() }} ứng dụng · Trang {{ $page->currentPage() }}/{{ $page->lastPage() }}
@if ($page->previousPageUrl()) ← Trước @endif @if ($page->nextPageUrl()) Tiếp → @endif
--}}
{{-- Modal QR No-Ads (giống style modal QR tải APK) --}}
Lưu ý: “Mới upload” không đồng nghĩa “đã Pass” hoặc “đã Public”. Marketing có thể tải APK của build cũ nhưng nên ưu tiên bản Public khi cần một phiên bản đã phát hành. Module này không cho phép thay đổi trạng thái kiểm thử hoặc phát hành.